Activityを切り替えずに、動的にListViewを作ったり消したりしていると、ガベージコレクションを何度実行しても回収されず、何故かメモリリークっぽい事になります。
以下再現ソースです。
package com.test; import android.app.Activity; import android.content.Context; import android.database.DataSetObserver; import android.os.Bundle; import android.os.Handler; import android.util.Log; import android.view.View; import android.view.ViewGroup; import android.widget.LinearLayout; import android.widget.ListAdapter; import android.widget.ListView; import android.widget.TextView; public class Test000Activity extends Activity { private LinearLayout layout; private int count = 0; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); layout = new LinearLayout(this); setContentView(layout); next(); } private class Next implements Runnable { public void run() { layout.removeAllViews(); count++; if (count == 10) { Log.d("test", "おわり"); return; } else { Log.d("test", "next:" + count); } MyListView listView = new MyListView(Test000Activity.this); listView.setAdapter(new MyListAdapter()); layout.addView(listView); next(); } } private void next() { new Handler().postDelayed(new Next(), 500); } private static class MyListView extends ListView { public MyListView(Context context) { super(context); } } private static class MyListAdapter implements ListAdapter { public int getCount() { return 50; } public Object getItem(int arg0) { return null; } public long getItemId(int position) { return 0; } public int getItemViewType(int position) { return 0; } public View getView(int position, View convertView, ViewGroup parent) { if (convertView != null) { return convertView; } TextView tv = new TextView(parent.getContext()); tv.setText("test"); tv.setMinimumHeight(40); return tv; } public int getViewTypeCount() { return 1; } public boolean hasStableIds() { return false; } public boolean isEmpty() { return false; } public void registerDataSetObserver(DataSetObserver observer) { } public void unregisterDataSetObserver(DataSetObserver observer) { } public boolean areAllItemsEnabled() { return true; } public boolean isEnabled(int position) { return true; } } }
これを実行すると、500msおきにMyListViewを作ったり消したりします。
10回繰り返すと終わります。
このあとで、DDMSのガベコレボタンを連打してDump HPROF fileしてみたのがこちら。
残っちゃっています。
ただ、デバッグ実行ではなく、通常の実行だとこのリークは検出されないので、実害は無いのですが、なんだか気持ち悪いのでなんとかしたいところです。
この辺ご存知の方はこっそり教えてもらえると助かります!