keb*_*bab 4 android memory-leaks listactivity listadapter
我有一个使用服务和一些列表活动的应用程序.当活动打开时,我可以看到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;
}
}
如果它反复(10-15次)打开活动,然后关闭活动,则堆大小(MB和#个对象)迅速增加!
你有没有运行垃圾收集器?DDMS中有一个用于此的按钮。
一旦运行了垃圾收集器,并且似乎没有任何要收集的内容(如LogCat中所述),您就可以始终转储堆并使用MAT或jhat对其进行检查。
我是否正确使用ListActivity?
删除活动中所有出现的getApplicationContext(),然后将其替换为this。该活动是一个Context,和你想被用Activity在这些地方。
同样,我不知道你为什么打电话getBaseContext()的Service,而不是仅仅使用this,因为Service也是一个Context。
| 归档时间: |
|
| 查看次数: |
3125 次 |
| 最近记录: |