我一直致力于此应用程序的数据库具有多兆字节的数据进行筛选。许多活动只是ListViews,通过数据库中的各种级别的数据下行,直到我们到达“文档”,这只是从数据库中提取并在手机上显示的HTML。我遇到的问题是,其中一些活动需要能够通过捕获键击并使用“like%blah%”重新运行查询来搜索数据库。除非用户首次加载数据并且用户首次进入击键时,否则这种工作相当快。我正在使用ResourceCursorAdapter并且我在后台线程中生成光标,但是为了执行listAdapter.changeCursor(),我必须使用Handler将其发布到主UI线程。这个特殊的调用然后冻结UI线程足够长来调出可怕的ANR对话框。我很好奇如何将其完全卸载到后台线程,以便用户界面保持响应,并且我们没有弹出ANR对话框。
仅仅为了完全公开,我最初返回了一个自定义模型对象的ArrayList并使用了ArrayAdapter,但是(可以理解)客户指出这是一个糟糕的内存管理,我对性能反正不满意。我真的想避免一个解决方案,我正在生成大量的对象列表,然后做一个listAdapter.notifyDataSetChanged / Invalidated()
以下是相关代码:
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);
}
};
答案 0 :(得分:1)
我发现很难相信listAdapter.changeCursor()
单独会花费足够的时间来引起ANR,假设您在后台线程中创建了Cursor
。重绘少量列表行时,不应该做那么多工作。我会仔细检查你在Handler中做的工作是否有限。也许考虑使用AsyncTask,这样可以更容易地将后台工作(doInBackground()
)与on-UI线程后处理(onPostExecute()
)分开。
您可以尝试直接更换适配器,再次使用新适配器中包含的新setAdapter()
再次调用Cursor
。
您可以查看AutoCompleteTextView
如何处理此方案,因为它使用SpinnerAdapter
进行动态过滤。也许它的一些技术可以适用于你的情况。
答案 1 :(得分:0)
刚刚在这里发布了一个答案:Android: Update Listview after Thread loads data from the net
简短:AsyncTask的onProgressUpdate方法可以触及视图:http://developer.android.com/reference/android/os/AsyncTask.html#onProgressUpdate(Progress...)