1

既存の例を書き換える単純なpdfリーダーを開発しています。私のアプリには、次と前の 2 つのボタンがあるカスタム ビューがあります。次のボタンをクリックすると、インターネットから PDF がダウンロードされ、ビューに表示されます。次または前のボタンがクリックされるたびに、次の showPdf() メソッドが呼び出されます。

public void showPdf(){

    RelativeLayout lout = (RelativeLayout)LayoutInflater.from(this).inflate(R.layout.main, null);
setContentView( lout );
m_vPDF = null;
m_vPDF = (PDFReader)lout.findViewById(R.id.PDFView);

m_vPDF.open( m_doc);


m_vPDF.setViewListener(m_vPDF);

LinearLayout bar_find = (LinearLayout)lout.findViewById(R.id.bar_find);
     //
btn_prev = (Button)bar_find.findViewById(R.id.btn_prev);
btn_next = (Button)bar_find.findViewById(R.id.btn_next);
//        
btn_prev.setOnClickListener(this);
btn_next.setOnClickListener(this);
}

PDFReader は、PDF を表示するビューアーを持つオブジェクトです。以下は、PDFReader コードの一部です。

public class PDFReader extends View implements PDFView.PDFViewListener,  

    ThumbView.ThumbListener
{

private PDFView m_viewer = null;

public PDFReader(Context context)
{
    super(context);
}
public PDFReader(Context context, AttributeSet attrs)
{
    super(context, attrs);
}
public void set_viewer( int view_style )
{

    switch( view_style )
    {
    case 1:
        m_viewer = new PDFViewHorz();
        break;
    case 2:
        m_viewer = new PDFViewScroll();
        break;
    case 3:
        m_viewer = new PDFViewSingle();
        break;
    case 4:
        m_viewer = new PDFViewSingleEx();
        break;
    case 5:
        m_viewer = new PDFViewReflow();
        break;
    default:
        m_viewer = new PDFViewVert();
        break;
    }
    if( m_viewer != null )
    {
        if( doc != null ) m_viewer.viewOpen(getContext(), doc, 0xFFCC0000, 4);
        m_viewer.viewSetAnnotListener( annot_listener );
        m_viewer.viewSetViewListener( view_listener );
        m_viewer.viewResize(getWidth(), getHeight());
        if( pos != null ) m_viewer.viewGoto(pos);
    }
}

私のshowPdfでは、ボタンがクリックされるたびにPDFReaderを初期化し、PDFReader内でPDFViewのインスタンスがPDFViewVertオブジェクトで初期化され、PDFReaderをnullに設定し、PDFViewをnullに設定してもガベージコレクションは行われません。その結果、メモリ不足エラーが発生しています。

これは、PDFViewVert の 14 個のインスタンスが作成され、割り当てが解除されていないことを示すダンプのメモリ分析です。

14 instances of "com.radaee.pdfex.PDFViewVert$1", loaded by "dalvik.system.PathClassLoader @ 0x412a0b08" occupy 19,602,792 (64.39%) bytes.

Biggest instances:

com.radaee.pdfex.PDFViewVert$1 @ 0x412a1ae8 - 1,543,040 (5.07%) bytes.
com.radaee.pdfex.PDFViewVert$1 @ 0x412c7c30 - 1,543,040 (5.07%) bytes.
com.radaee.pdfex.PDFViewVert$1 @ 0x418bdf78 - 1,543,040 (5.07%) bytes.
com.radaee.pdfex.PDFViewVert$1 @ 0x41a382f8 - 1,543,040 (5.07%) bytes.
com.radaee.pdfex.PDFViewVert$1 @ 0x41a4df50 - 1,543,040 (5.07%) bytes.
com.radaee.pdfex.PDFViewVert$1 @ 0x41eaf1c0 - 1,543,040 (5.07%) bytes.
com.radaee.pdfex.PDFViewVert$1 @ 0x4202a8e0 - 1,543,040 (5.07%) bytes.
com.radaee.pdfex.PDFViewVert$1 @ 0x421aaa10 - 1,543,040 (5.07%) bytes.
com.radaee.pdfex.PDFViewVert$1 @ 0x4233dbf8 - 1,543,040 (5.07%) bytes.
com.radaee.pdfex.PDFViewVert$1 @ 0x412a0bf0 - 1,543,024 (5.07%) bytes.
com.radaee.pdfex.PDFViewVert$1 @ 0x412bbf58 - 1,390,792 (4.57%) bytes.
com.radaee.pdfex.PDFViewVert$1 @ 0x412f0790 - 1,390,792 (4.57%) bytes.
com.radaee.pdfex.PDFViewVert$1 @ 0x424c4b50 - 1,390,792 (4.57%) bytes.


Keywords
com.radaee.pdfex.PDFViewVert$1
dalvik.system.PathClassLoader @ 0x412a0b08

どんな助けでも大歓迎です..ありがとう、

4

3 に答える 3

2

Java GC は、参照されなくなったオブジェクトを必ずしもクリーンアップするとは限りません。これまでに十分なメモリがある場合は、何もしないことを決定できます。

メモリ リークの可能性を実際にチェックするには、メモリ プロファイラのみを使用します。

しかし、もっと簡単なチェックを試すことができます。アプリケーションのヒープ サイズを小さくして、 を呼び出してくださいSystem.gc()。これは GC をトリガーすることを保証するものではありませんが、オブジェクトの削除を開始する場合は、メモリ リークが発生していない可能性が高いことを示しています。

于 2012-12-12T06:01:23.650 に答える
1

これを試してください:

Runtime.getRuntime().gc();

これを変える

m_vPDF = null;

に、

if (m_vPDF != null){
  m_vPDF.recycle();
  m_vPDF = null;
}

これは、未使用のオブジェクトをクリーンアップするのに役立ちます。

お役に立てば幸いです。

ありがとう。

于 2012-12-12T06:39:32.283 に答える
0

個人的には、代わりにカスタム アダプターを使用するのが最善の方法だと思います。そうすれば、ビューが再利用され、pdfview の 23 のインスタンスを取得できなくなります。それは1つだけを保存し、次または前を押す代わりにスワイプできるようにします. 残念ながら、これらのデバイスには、得たものに起因する多くのメモリがありません

于 2012-12-12T06:40:13.500 に答える