Android CursorAdapters,ListViews和后台线程

我一直在研究的这个应用程序有数据库,可以筛选出数兆字节的数据。 许多活动只是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); } }; 

我发现很难相信listAdapter.changeCursor()单独占用足够的时间来引起ANR,假设你在后台线程中创建了Cursor 。 重新制作一些列表行时,不应该做那么多工作。 我会仔细检查一下你在Handler中做的工作是否有限。 也许考虑使用AsyncTask,这样可以更容易地将后台工作( doInBackground() )与on-UI线程后处理( onPostExecute()onPostExecute()

您可以尝试直接替换适配器,方法是再次使用新适配器中包含的新Cursor调用setAdapter()

您可以查看AutoCompleteTextView如何处理此场景,因为它使用SpinnerAdapter过滤。 也许它的一些技术可以适用于你的情况。

刚刚在这里发布了一个答案: Android:在线程从网络加载数据后更新Listview

简短:AsyncTask的onProgressUpdate方法可以触摸视图: http : //developer.android.com/reference/android/os/AsyncTask.html#onProgressUpdate(Progress …)