私が取り組んできたこのアプリケーションには、複数のメガバイトのデータを含むデータベースがあります。多くのアクティビティは、ListViewsだけでデータベース内のさまざまなレベルのデータに降下し、 "ドキュメント"に到達します。これはDBから取得され、電話に表示されるHTMLです。私が抱えている問題は、これらのアクティビティの中には、キーストロークをキャプチャしてクエリーを "like%blah%"で再実行することによってデータベースを検索する能力が必要なことです。これは、ユーザーが最初にデータをロードしているときと、ユーザーがキーストロークを最初に入力したときを除いて、合理的に迅速に機能します。私はResourceCursorAdapterを使用しており、バックグラウンドスレッドでカーソルを生成していますが、listAdapter.changeCursor()を実行するには、ハンドラを使用してメインUIスレッドにポストする必要があります。この特定の呼び出しでは、のUIスレッドが凍って恐ろしいANRダイアログが表示されます。私はこれをバックグラウンドスレッドにどのようにしてオフロードできるのか不思議で、ユーザーインターフェイスは応答性があり、ANRダイアログが表示されません。Android CursorAdapters、ListViews、およびbackground threads
私はもともと、カスタムモデルオブジェクトのArrayListを返していましたが、ArrayAdapterを使用していましたが、(おそらく)顧客はそれが悪いメモリ管理であると指摘しました。私はそれを見つける
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);
}
};
を、すべてが幸せだったと、バックグラウンドで実行されていました。 updateHandler.post(新しいRunnableを(){ 公共ボイドラン(){ listAdapter.changeCursor(CUR); }});:私はこれを追加したら すべてがすごくうんざりになりました。 – MattC
奇妙な質問:上記のコードでfilterLockとは何ですか?おそらく致命的な抱擁やデッドロックに陥っていますか? – CommonsWare
これは、最初のクエリが実行されている間にユーザーが入力を続けた場合に使用すると予想されていたロックです。 changeCursorは、notifyDataSetChanged()を呼び出し、ハングしている場所で、CursorAdapterの実際のコードを実行します。 – MattC