我有一个适用于模拟器的应用程序,但在真实设备上进行测试时会间歇性地崩溃。我正在运行Code Overtones Android Crash报告的修改版本。 (http://jyro.blogspot.com/2009/09/crash-report-for-android-app.html)电子邮件原因说明:
适配器的内容已更改,但ListView未收到 通知。确保未修改适配器的内容 来自后台线程,但仅来自UI线程。 [在 ListView(2131296303,类android.widget.ListView)与Adapter(类 android.widget.SimpleAdapter)]
代码不会修改UI主线程之外的适配器。对适配器的所有访问都是通过AsyncTask的onPostExecute进行的。代码是:
@Override
protected void onPostExecute(String result) {
MyLog.d(TAG, "onPostExecute");
foodDescArrayList.clear();
int entries = holdFoodDescArrayList.size();
HashMap<String, String> listEntry;
for (int i = 0; i < entries; i++) {
listEntry = new HashMap<String, String>();
listEntry = holdFoodDescArrayList.get(i);
foodDescArrayList.add(listEntry);
}
holdFoodDescArrayList.clear();
hideProgress();
foodDescAdapter.notifyDataSetChanged();
String ents = " entries";
if (rowsReturned == 1) {
ents = " entry";
}
foodDescHeader.setText("Page " + Integer.toString(currentPage + 1)
+ " of " + Integer.toString(pageCount) + " (" + Integer.toString(rowsReturned) + ents + ")");
loadActive = false;
}
holdFoodDescArrayList是一个独立的列表,填充在SQLite数据库的后台任务中。 foodDescArrayList是与ListView适配器关联的数组。 (我发现在以这种方式排队时会有性能提升。也许是因为在数据库访问期间适配器不在循环中。开销较少?)
崩溃始终发生在主键退出后的第一个条目(onCreate)上,然后重新进入调用列表活动的顶级活动。在连续测试期间,崩溃之间的时间为30分钟至2小时。崩溃的代码已经遍历了数百次并且是线性的,没有退出。
我在查看代码时可以找到的唯一可能的漏洞是数组加载前的clear()。明确的功能是作为一个变化而作为第二个变化添加的吗?有时间考虑吗?列表中有1到24个条目,因此加载应该花费毫秒而不是秒......
我正在寻找想法和线索。请扫描代码,看看代码中是否有明显的错误或副作用。它是应用程序中唯一更改ListView关联数组数据的位置。后台代码仅改变保持数组。
请不要在答案中输入完整的代码重写。我正在继续尝试找到原因和原因。我不想浪费你几分钟的时间。我会在接下来的几天里经常看这篇文章并回答我发现的任何问题。谢谢你的帮助...
-----------更新以添加请求的代码----------
onCreate中的代码是:
setContentView(R.layout.fooddeslist);
foodDescHeader = (TextView) findViewById(R.id.foodDescHeading);
foodDescListView = (ListView) findViewById(R.id.foodDescList);
foodDescArrayList = new ArrayList<HashMap<String, String>>();
holdFoodDescArrayList = new ArrayList<HashMap<String, String>>();
foodDescAdapter = new SimpleAdapter(this, foodDescArrayList,
R.layout.longdescitem, new String[] { GC.FOODDESCLIST_LINE1,
GC.FOODDESCLIST_LINE2 },
new int[] { R.id.longdescListItemLine1,
R.id.longdescListItemLine2 });
foodDescListView.setAdapter(foodDescAdapter);
registerForContextMenu(foodDescListView);
数组条目是:
listEntry = new HashMap<String, String>();
hold数组是适配器数组的副本。 hold数组加载到AsyncTask中的doInBackground函数中。我会显示背景代码,但它大约有500行代码。最终结果是保持数组加载了2行显示和每个条目唯一的辅助数据。选择条目时使用的其他表中各种数据位的行ID。重复的表允许我加载数组(到千兆赫处理器)加载数组。 UI运行后执行传输只需几毫秒。
longdescitem.xml是:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView android:id="@+id/longdescListItemLine1"
android:textStyle="italic"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="#ff9900"
/>
<TextView android:id="@+id/longdescListItemLine2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="#b89300"
/>
</LinearLayout>
R.layout.fooddesclist是:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
android:id="@+id/foodDescHeading"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_marginLeft="2dip"
android:text="Page 1 of 10 (nnn entries)"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textColor="#b89300" />
<ImageButton
android:id="@+id/foodDescForward"
android:layout_width="50px"
android:layout_height="50px"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:layout_marginRight="12dip"
android:layout_marginTop="5dip"
android:background="@drawable/forward"
android:clickable="true"
android:onClick="foodDescForwardClicked" />
<ImageButton
android:id="@+id/foodDescBack"
android:layout_width="50px"
android:layout_height="50px"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_marginLeft="12dip"
android:layout_marginTop="5dip"
android:background="@drawable/back"
android:clickable="true"
android:onClick="foodDescBackClicked" />
<View
android:id="@+id/foodDescSpacer1"
android:layout_width="match_parent"
android:layout_height="2dp"
android:layout_alignParentLeft="true"
android:layout_below="@id/foodDescForward"
android:layout_marginBottom="2dip"
android:layout_marginTop="2dip"
android:background="@drawable/divider" />
<ListView
android:id="@+id/foodDescList"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_below="@id/foodDescSpacer1"
android:layout_marginLeft="2dip"
android:layout_marginRight="2dip"
android:cacheColorHint="#00000000"
android:divider="#b89300"
android:dividerHeight="1.0px" />
</RelativeLayout>
--------另一次更新--------------
我在opPostExecute函数中添加了一些代码。
protected void onPostExecute(String result) {
MyLog.d(TAG, "onPostExecute");
foodDescArrayList.clear();
foodDescAdapter.notifyDataSetChanged();
try {
Thread.sleep(300);
} catch (InterruptedException e) {
MyLog.d(TAG, "Sleep failed: " + e.getMessage());
}
int entries = holdFoodDescArrayList.size();
HashMap<String, String> listEntry;
for (int i = 0; i < entries; i++) {
listEntry = new HashMap<String, String>();
listEntry = holdFoodDescArrayList.get(i);
foodDescArrayList.add(listEntry);
}
holdFoodDescArrayList.clear();
hideProgress();
foodDescAdapter.notifyDataSetChanged();
String ents = " entries";
if (rowsReturned == 1) {
ents = " entry";
}
foodDescHeader.setText("Page " + Integer.toString(currentPage + 1)
+ " of " + Integer.toString(pageCount) + " (" + Integer.toString(rowsReturned) + ents + ")");
loadActive = false;
}
在Atrix上进行了两个小时的稳定测试之后,它还没有崩溃。在代码之前,我会在2小时内至少崩溃一次,有时两次。我在清除后添加了notifydatasetchanged,然后以300毫秒的睡眠进行跟踪。我认为操作系统正在踩踏脚趾,因为原始通知丢失了。虽然数据库查询最多可能需要8秒,但大部分时间都是即时回答。进度对话框从未有机会完全设置。屏幕会闪烁,然后列表视图会显示。进度显示无法识别。 (在preExecute函数中打开进度对话框。)整个AsyncTask在不到300毫秒的时间内完成。也许这是一个修复,也许不是。
答案 0 :(得分:0)
我自己回答这个问题,以回答这个问题。