我一直在处理的这个应用程序有数据库与多兆字节的数据进行筛选。很多活动只是ListViews在数据库中通过各种级别的数据递减,直到我们到达“文档”,这只是从数据库中提取并显示在手机上的HTML。我遇到的问题是,其中一些活动需要能够通过捕获键击并在其中重新运行查询并使用“like%blah%”来搜索数据库。除非用户第一次加载数据和用户首次输入按键时,这种方式可以合理快速地进行。我正在使用ResourceCursorAdapter,我在后台线程中生成游标,但为了做一个listAdapter.changeCursor(),我必须使用Handler将它发布到主UI线程。然后这个特定的调用会冻结UI线程足够长的时间带来可怕的ANR对话框。我很好奇我如何将它完全卸载到后台线程,以便用户界面保持响应,并且我们没有弹出ANR对话框。我最初只是返回一个自定义模型对象的ArrayList并使用ArrayAdapter,但(可以理解)客户指出这是糟糕的内存管理,而且我对性能不满意。我真的想避免一个解决方案,我生成对象的庞大名单,然后做一个listAdapter.notifyDataSetChanged /废弃()Android CursorAdapters,ListViews和后台线程
这里是有问题的代码:
private Runnable filterDrugListRunnable = new Runnable() {
public void run() {
if (filterLock.tryLock() == false) return;
cur = ActivityUtils.getIndexItemCursor(DrugListActivity.this);
if (cur == null || forceRefresh == true) {
cur = docDb.getItemCursor(selectedIndex.getIndexId(), filter);
ActivityUtils.setIndexItemCursor(DrugListActivity.this, cur);
forceRefresh = false;
}
updateHandler.post(new Runnable() {
public void run() {
listAdapter.changeCursor(cur);
}
});
filterLock.unlock();
updateHandler.post(hideProgressRunnable);
updateHandler.post(updateListRunnable);
}
};
之前,我添加了changeCursor电话,一切很高兴,并在后台运行。有一次,我添加了这个: updateHandler.post(新的Runnable(){ 公共无效的run(){ listAdapter.changeCursor(现);} }); 一切都变得糟糕。 – MattC 2009-08-27 13:04:48
奇怪的问题:什么是你的代码中的filterLock?你是否可能陷入致命的拥抱或僵局? – CommonsWare 2009-08-27 16:42:30
这只是一个锁,我们曾预料会使用的情况下,用户在第一个查询运行时保持打字状态。 逐步调整CursorAdapter的实际代码,changeCursor调用notifyDataSetChanged(),这是挂起的位置。 – MattC 2009-08-27 16:49:48