我一直在處理的這個應用程序有數據庫與多兆字節的數據進行篩選。很多活動只是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