首页 文章

我使用Android中的ListActivity进行内存泄漏

提问于
浏览
3

我有一个使用服务和一些列表活动的应用程序 . 当活动打开时,我可以看到DDMS中的堆使用量增加,当活动关闭时,堆使用量略有下降 . 此时此服务仍在后台运行 . 如果通过重新运行应用程序再次启动活动并且关闭,则堆使用量再次增加然后减少,但在首次打开活动之前永远不会返回到原始级别 . 如果反复(10-15次)打开活动,则关闭活动,堆大小(MB和#Objects)气球!

我希望ListActivity的onDestroy能够在它被破坏时自行处理 . 我错过了什么?我是否正确使用ListActivity?

类似于我的真实代码的测试应用程序如下 . 创建一个新的Android应用程序,将其添加到清单:

<service android:name="LeakTestService"/>

和这些java文件:

LeakTestActivity.java
-------------
package LeakTest.Test;

import java.util.ArrayList;
import java.util.HashMap;

import android.app.Activity;
import android.app.ListActivity;
import android.content.Intent;
import android.os.Bundle;
import android.widget.ArrayAdapter;
import android.widget.SimpleAdapter;

public class LeakActivity extends ListActivity {
    ArrayList> _Data=new ArrayList>();
    ArrayAdapter _Adapter;

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        Intent svc = new Intent(this.getApplicationContext(), LeakTestService.class);
        startService(svc);

        // the problem happens with both SimpleAdapter and ArrayAdapter
        //_Adapter = new SimpleAdapter(this.getApplicationContext(), _Data, android.R.layout.two_line_list_item, new String[] { "line1","line2" }, new int[] { android.R.id.text1, android.R.id.text2 });
        _Adapter = new ArrayAdapter(this.getApplicationContext(), android.R.layout.simple_list_item_1, new String[] {"data1","data2"} );

        // if this line is removed, the heap usage never balloons if you repeatedly open+close it
        getListView().setAdapter(_Adapter);
    }

    @Override
    public void onDestroy() {
        _Adapter=null; // this line doesn't help
        getListView().setAdapter(null); // neither does this line
        super.onDestroy();
    }
}



LeakTestService.java
--------
package LeakTest.Test;

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.widget.Toast;

public class LeakTestService extends Service {
    @Override
    public void onStart(Intent intent, int startId) {
        Toast.makeText(getBaseContext(), "Service onStart", Toast.LENGTH_SHORT).show();
    }

    @Override public void onDestroy() {
        Toast.makeText(getBaseContext(), "Service onDestroy", Toast.LENGTH_SHORT).show();
        }

    @Override
    public IBinder onBind(Intent intent) {
        // TODO Auto-generated method stub
        return null;
    }
}

2 回答

  • 4

    如果反复(10-15次)打开活动,则关闭活动,堆大小(MB和#Objects)气球!

    你有没有运行垃圾收集器?在DDMS中有一个按钮 .

    一旦你运行了垃圾收集器并且它似乎没有收集任何内容(如LogCat中记录的那样),你总是可以转储堆并使用MATjhat进行检查 .

    我是否错误地使用了ListActivity?

    删除活动中出现的所有 getApplicationContext() ,并将其替换为 this . 活动是 Context ,您希望在这些地方使用 Activity .

    同样,我不知道为什么你在 Service 中调用 getBaseContext() ,而不是仅仅使用 this ,因为 Service 也是 Context .

  • 8

    我有同样的问题,但我发现问题只发生在我调试时 . 在“正常”运行中,所有活动都消失了 .

相关问题