2009-08-26 18 views
2

私が取り組んできたこのアプリケーションには、複数のメガバイトのデータを含むデータベースがあります。多くのアクティビティは、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); 
    } 
}; 

答えて

1

:私は本当にここで

は、問題のコードです)(私はオブジェクトの巨大なリストを生成し、その後listAdapter.notifyDataSetChanged /無効化さをやっているソリューションを避けるしたいのですがあなたがバックグラウンドスレッドでCursorを作成したと仮定すると、listAdapter.changeCursor()だけではANRを引き起こすのに十分な時間がかかります。一握りのリスト行を再描画する必要があるだけの作業はありません。 Handlerで何をしているのかは、あなたが思うように限られているかどうかを再確認します。おそらくAsyncTaskを使用することを検討してください。バックグラウンド作業(doInBackground())とUI上のスレッドの後処理(onPostExecute())を簡単に分けることができます。

新しいアダプタで新しいCursorをラップして、setAdapter()を再度呼び出すだけで、アダプタを完全に交換できます。

は、SpinnerAdapterでオンザフライのフィルタリングを行うので、このシナリオをどのように処理するかを見ることができます。おそらくそのテクニックのいくつかがあなたのケースに当てはまるかもしれません。

+0

を、すべてが幸せだったと、バックグラウンドで実行されていました。 updateHandler.post(新しいRunnableを(){ 公共ボイドラン(){ listAdapter.changeCursor(CUR); }});:私はこれを追加したら すべてがすごくうんざりになりました。 – MattC

+0

奇妙な質問:上記のコードでfilterLockとは何ですか?おそらく致命的な抱擁やデッドロックに陥っていますか? – CommonsWare

+0

これは、最初のクエリが実行されている間にユーザーが入力を続けた場合に使用すると予想されていたロックです。 changeCursorは、notifyDataSetChanged()を呼び出し、ハングしている場所で、CursorAdapterの実際のコードを実行します。 – MattC

関連する問題