【发布时间】:2012-01-26 12:58:16
【问题描述】:
我有一个活动可以做到这一点:
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.list);
ListView lv = (ListView) findViewById(R.id.ListList);
lv.setItemsCanFocus(true);
lv.setOnItemClickListener(this);
adapter = new ListAdapter(this, lv, model, R.layout.simple, this);
lv.setAdapter(adapter);
}
我的列表适配器类如下所示。
public static class ListAdapter extends ArrayAdapter<ListItem>
public ListAdapter(Activity activity, ListView lv, List<ListItem> model, int resource, OnActionClickListener onActionClickListener) {
super(activity, android.R.layout.simple_list_item_1, model);
....
}
如果我改变方向,大约 20 次,它将耗尽内存并给我这样的错误:
12-22 17:33:44.977: E/dalvikvm-heap(29145): 1536000-byte external allocation too large for this process.
如果我不在 onCreate 中设置其余代码(过去的 setContentView),我没有问题。
我猜我正在(不经意间)持有活动的一个实例,但我不确定如何。
有什么想法吗?
tia.
所以导致问题的原因是“lv.setAdapter(adapter);” - 如果我注释掉那行,我没有问题......我在 onDestroy() 中尝试了 lv.setAdapter(null) - 没有帮助。我还将这个(http://stackoverflow.com/questions/1147172/what-android-tools-and-methods-work-best-to-find-memory-resource-leaks)添加到 onDestroy() - 似乎没有来帮忙。
所以,我已将其范围缩小到尽可能小。
这里是主要的 TestAppActivity.java 文件。
package com.junk.test;
import java.util.ArrayList;
import java.util.List;
import android.app.Activity;
import android.content.pm.ActivityInfo;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.view.ContextMenu;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
public class TestAppActivity extends Activity {
protected ArrayList<ListItem> model = new ArrayList<ListItem>();
protected ListAdapter adapter = null;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
ListView lv = (ListView) findViewById(R.id.ListList);
lv.setItemsCanFocus(true);
adapter = new ListAdapter(this, lv, model);
lv.setAdapter(adapter);
if (savedInstanceState == null) {
Log.i("test", "@@ start");
new Thread(new Runnable() {
@Override
public void run() {
try {
boolean change = true;
Thread.sleep(4 * 1000);
for (int ii = 0; ii < 200; ii++) {
setRequestedOrientation(change ? ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE : ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
Thread.sleep(4 * 1000);
change = !change;
Log.i("test", "@@ change: " + (ii+1));
}
} catch (Exception e) {
e.printStackTrace();
} finally {
Log.i("test", "@@ complete!");
}
}
}).start();
}
}
@Override
protected void onDestroy() {
super.onDestroy();
// doesn't make any difference.
// ListView lv = (ListView) findViewById(R.id.ListList);
// lv.setAdapter(null);
// adapter.clear();
// adapter = null;
unbindDrawables(findViewById(R.id.ListList));
System.gc();
}
private void unbindDrawables(View view) {
if (view == null) { return; }
if (view.getBackground() != null) {
view.getBackground().setCallback(null);
}
if (view instanceof ViewGroup) {
for (int i = 0; i < ((ViewGroup) view).getChildCount(); i++) {
unbindDrawables(((ViewGroup) view).getChildAt(i));
}
if (view instanceof AdapterView) {
} else {
((ViewGroup) view).removeAllViews();
}
}
}
public static class ListItem {
public int x;
}
public static class ListAdapter extends ArrayAdapter<ListItem> implements View.OnClickListener {
public ListAdapter(Activity activity, ListView lv, List<ListItem> model) {
super(activity.getApplicationContext(), android.R.layout.simple_list_item_1, model);
}
@Override
public void onClick(View v) {
}
}
}
这里是 main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
android:background="@drawable/player_background">
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/hello" />
<ListView
android:id="@+id/ListList"
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:choiceMode="singleChoice"
android:cacheColorHint="#00000000"
android:dividerHeight="3dp"
android:overScrollFooter="@null" />
</LinearLayout>
而且它仍然在泄漏 - 大约需要 110 次方向更改,但最终它给出了分配错误!
【问题讨论】:
-
您的列表中有多少项?
-
布局中没有 ListView 是否会出现问题?在缩小范围之前,您需要开始整理内容。
-
没有列表视图,错误不会发生。具体来说,如果我没有在列表视图上设置适配器 lv.setAdapter(adapter);那我也看不到了。
标签: android memory out-of-memory orientation