1

我正在开发一个简单的 pdf 阅读器,重写一个现有的例子。我的应用程序有一个自定义视图,其中包含下一个和上一个按钮。单击下一个按钮时,它会从 Internet 下载 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,也不会进行垃圾收集。结果,它导致内存不足错误。

这是转储的内存分析,它显示了 14 个 PDFViewVert 实例已创建且从未释放。

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

就个人而言,我认为您最好的选择是使用自定义适配器,这样它将重用视图,并且您不会获得 23 个 pdfview 实例。它只会保存一个,它会让你能够滑动而不是点击下一个或上一个。不幸的是,这些设备没有你所拥有的大量内存

于 2012-12-12T06:40:13.500 回答