(コンテンツリゾルバーを介して)他の複数のコンテンツプロバイダーにクエリを実行できるコンテンツプロバイダーがあり、連絡先データのマージを実行します。
基本的に、私はasyncTaskを拡張し、データを処理しました。私のメインUIスレッドでは、次のことを行います
cancelAllExistingTask();
proiverTest1 = new ProviderTask(getActivity, MyActivity.this.callBack).execute(SearchString, elementId1);
proiverTest2 = new ProviderTask(getActivity, MyActivity.this.callBack).execute(SearchString, elementId2);
proiverTest3 = new ProviderTask(getActivity, MyActivity.this.callBack).execute(SearchString, elementId3);
proiverTest4 = new ProviderTask(getActivity, MyActivity.this.callBack).execute(SearchString, elementId4);
そこで、ProviderTaskコンストラクターの一部としてProviderTaskの4つのインスタンスを作成し、callBackクラスのインスタンスに実装されているインターフェイスを渡します。
class CallBackClass implements MyCallBackIF{}
doInBackground中のProviderTaskは、1つのプロバイダーに対してContentResolver.query()を起動します。4つのタスクすべてで同じプロバイダーが使用されます。ただし、elementIdに基づいて、onPostExecute()を介してインターフェイスに返されます。カーソル配列のelementIdは、配置する必要があります(以下の**を参照)。
contentProviderは、渡されたURIを解析し、URIに基づいて、他の1つのContentProviderにデータを照会します。これはローカルデータであるか、サーバーからリモートである可能性があります。次に、ソースによっては、他のデータ(ローカル)とマージし、マージされたデータを含む新しいカーソルを提供する場合があります。個々のコンテンツプロバイダー->コンテンツリゾルバー->コンテンツプロバイダー->コンテンツリゾルバーは非常に高速です。そして、私たちが持っているいくつかの異なるアプリ間で検索集約を提供するのにいくらか便利です。プロバイダーは実際にasyncTaskを生成してリモートコンテンツプロバイダーデータをロードし、アクティビティに戻る前にデータの戻りが完了するのを待機する同期ブロックがあります。この理由の一部は、検索する複数のプロバイダーを持つURIを渡すことができたためです。複数のコンテンツリゾルバークエリを独自のマージカーソルに起動するマージ。(ただし、現時点では、非同期タスクで実行されるのは1要素のマージカーソルです)。
**私が行っているのは、マージカーソルとCursor []を使用して、さまざまな異なるプロバイダーからのマージされたデータに基づいてリストビューを更新することです。あなたは質問しているかもしれません、なぜコンテンツプロバイダーにそれが私たちのために働くことを許可しないのですか?やってみました。それは私たちにとってはうまくいかなかったようですが、提案を受け入れています。
つまり、MergeProviderクエリ(ContentProvider1、ContentProvider2、ContentProvider3、ContentProvider4)と、ContentProvider3もContentProvider 1にクエリを実行して、一部のデータをマージする必要がある場合です。ContentProvider 3および4はリモート(サーバーベース)です
予測検索の場合、最も早く戻ってくる検索結果を最初に表示する必要があります。そして、他の人が戻ってきたときに少しずつ入ります。新しい文字が入力された場合は、結果セット全体をダンプして、新しいクエリを待ちます。これが起こっていることであり、どこかでブロックされているようです。 (AsyncTaskのスレッド優先度を上げようとしましたが、ExecuteExecutorと独自のExecutorおよびプールがあります(非同期タスクの最大値を10から100に上げます)。結果はありません)。
したがって、誰かが文字「a」を入力します-コンテンツプロバイダー1とコンテンツプロバイダー2は、たとえば0.050秒で戻ります。コンテンツプロバイダー4は、たとえば0.100秒で戻ります。そして、コンテンツプロバイダー3は5.00秒で戻ります。(5.00の遅延は、テストしているテストサーバーに関連していますが、ブロッキングで発生している問題が明らかになっています)。
ここで、入力を続け、文字列に「albert」と表示されている場合は、「al」の新しいAsyncTaskが起動された可能性があります。これは、すぐに返されるものと返されないものがあります。プロバイダー3がまだ応答を待っているとしましょう。結果が返されるまでに予測検索が変更された場合、コードは結果を破棄します。(これは問題ありません)。そのため、AsyncTasks'albert'の別のラウンドを起動します。ここで、プロバイダー3が5秒の応答でまだオフになっていることを思い出してください。
AsyncTaskとCallingメソッド(ハンドラー)の両方にログを追加しました。表示されているのはAsyncTaskが作成されていることですが、SearchProvider3が結果を返すまで(そして結果が破棄されるまで)doInBackground()が開始されることはありません。なぜこれが起こっているのか、私はかなり混乱しています。ただし、基本的に他のAsyncTaskオブジェクトをブロックしています。10 AsyncTasksの最大制限が原因でない限り、別のAsyncTaskが戻るまでdoInBackground()が呼び出されない原因がわかりませんか?ThreadPoolExecutorの独自の実装(およびThreadPoolExecutorの2つの異なるインスタンスの作成)でも、同じ問題が発生します。
プロバイダー3のクエリメソッドでthread.sleep(60000)を追加すると、非常にわかりやすくなります。基本的に、ブロックを開始する前に5つの非同期タスクが呼び出されるように見えます。私たちの目標は、他の長時間実行されるタスクとは関係なく、ローカルマッチングの結果をより速く戻すことでした。これは、低速(3g)ネットワークでより明白になります。
たぶん、これに非同期タスクを使用するのではなく、ランナブルを使用するだけでよいのでしょうか。
ありがとう。