2010-11-30 14 views
3

"リアルタイム"でデータベースを検索するアプリケーションを作成しています。 つまり、ユーザーが文字を押すと、検索結果リストが更新されます。AsyncTaskを使用した「リアルタイム」検索?

検索に時間がかかるため、バックグラウンドで検索し、検索を再開するために新しいキーを押す必要があります。ユーザーが「a」を押すと(コードが「a」の検索を開始する)、「b」を押すと、コードは「a」検索が終了するのを待つことなく、「ab」の検索を開始します"a"検索を停止し、新しい "ab"検索を開始します。

  • これを行うには、私はAsyncTaskで検索を行うことにしました。これは賢明な決断ですか?

Now - キー押下が検出されるたびに、私はAsyncTaskを実行しているかどうかを調べるためにテストします。私がすれば - 私はそれを(AsyncTask内のブール値を使って)シグナルを止めるべきです。次に、10ミリ秒以内にAsyncTaskを再テストし、終了したかどうかを確認し、新しい検索を開始するタイマーを設定します。

  • これはスマートな方法ですか?それとも別のアプローチがありますか?

TIA

+0

データベースから検索する場合は、実際に検索を停止することはできません。それは本当にそれを長く取っていますか?そうであれば、そのような動的検索の完了を実装すべきではないでしょう。 – Falmarri

+0

実行可能なAsyncTaskの数には制限があります。以前のバージョンのAndroidではそれは低かった。最近のものでは無視することができます。 – Reno

答えて

2

まずはい、AsyncTaskはこれを行うには良い方法です。私があなたのアプローチで見る問題は、何かが死ぬのを待っているタイマーです。 asyncTaskを呼び出すと、その参照を保持します。それがあなたのために状態を保つようにしてくださいそれはあなたが探しているか、それが戻ってきたかどうかを知っている。ユーザーが別の文字をクリックすると、asyncTaskをキャンセルすることができます。このようなもの:

public void onClick() { 
    if(searchTask != null) { 
     searchTask.cancel(); 
    } 

    searchTask = new SearchTask(MyActivity.this).execute(textInput.getText()); 
} 

public class SearchTask extends AsyncTask<String,Integer,List<SearchResult>> { 
    private boolean canceled = false; 

    protected onPostExecute(List<SearchResult> results) { 
     if(!canceled) { 
      activity.handleResults(results); 
     } 
    } 

    public void cancel() { 
     canceled = true; 
    } 
} 

これは、onPostExecute()がUIスレッド上にあるため安全です。また、cancel()はUIスレッドからのみ呼び出されるため、スレッドの安全性の問題はなく、同期する必要はありません。スレッドダイを見る必要はありません。 GCがクリーンアップするようにしてください。 AsyncTaskへの参照を削除すると、それは単にクリーンアップされます。 AsyncTaskがブロックされているのは、バックグラウンドスレッドのみをハングアップするためです。タイムアウトが発生すると、onPostExecute()を呼び出して再開します。これにより、Timerを使用せずにリソースを最小限に保ちます。

このアプローチについて考慮すべき事項。新しい文字が入力されるたびに新しいリクエストを送信すると、最初の数文字が最大の検索結果を生成するため、サーバーに負荷がかかる可能性があります。サーバーから返す結果の数を制限するか(例:最大10-50件)、結果を保持するのに十分な文字が入力されるまで待機します(3など)。ユーザータイプをより多くの文字にすることの問題は、フィードバックが3文字までキックオフされないことです。しかし、それはあなたのサーバーのヒットを劇的に減らすということです。

+0

こんにちは、ありがとう!ここでの1つの質問 - あなたは(searchTask!= null)をテストしていますキャンセル(または終了)後にnullに設定されている場所は表示されません。 –

+0

これは主に、タスクが実行されていない最初の時間です。タスクが終了したときにnullに設定する場合は、AsyncTaskがnullに設定できないため、Activity.handlResults()メソッドでその作業を行います。新しいAsyncTaskに設定すると、以前の参照が解放されるため、onClick()メソッドでは実行しません。 – chubbsondubs

関連する問題