1

私は、(コンテンツリゾルバを介して)複数の他のコンテンツプロバイダに問い合わせることができ、連絡先データのいくつかのマージを行うコンテンツプロバイダを持っています。コンテンツプロバイダは単一のブロックインスタンスですか?

基本的に私は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の4つのインスタンスを作成します、ProviderTaskコンストラクタの一部として、私は、コールバッククラスの私のインスタンスで実装されているインタフェースに渡します。

class CallBackClass implements MyCallBackIF{} 

doInBackground中のProviderTaskは、ContentResolver.query()をONEプロバイダに起動します。同じプロバイダが4つのタスクすべてで使用されます。しかし、elementIdに基づいて、onPostExecute()を介してインターフェイスに返されます。これは、配置されるべきカーソル配列のelementIdです(以下を参照してください)。

contentProviderは渡されたURIを解析し、そのURIに基づいて、他の1つのContentProviderにデータを問い合わせます。これは、ローカルデータでも、サーバーからのリモートデータでもかまいません。その後、ソースに応じて、他のデータ(ローカル)とマージし、マージされた新しいデータ付きのカーソルを戻すことができます。個々のコンテンツプロバイダ - >コンテンツリゾルバ - >コンテンツプロバイダ - >コンテンツリゾルバは非常に高速です。私たちが持っているいくつかの異なるアプリケーション間で検索集約を提供するためにはいくらか役立ちます。プロバイダは実際には、リモートコンテンツプロバイダのデータをロードするasyncTaskを生成し、アクティビティに戻る前にデータを返すのを待つ同期ブロックがあります。この理由の1つは、複数のプロバイダがある&を検索するuriを渡すことができ、複数のコンテンツリゾルバクエリを自身のマージカーソルに送り出すことができることです。 (しかし、今は非同期タスクで実行されるMerge Cursor w/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の遅延は、テスト対象のテストサーバーに関連していますが、私たちが見ている問題を公開しています)。

今、彼らは入力し続け、そして文字列が 「アルバート」 それはすぐにいくつかのリターン「アル」の新しい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)ネットワークではっきりします。

私たちはこれに非同期タスクを使用すべきではなく、単にランナブルを使うべきでしょうか?

ありがとうございました。

答えて

1

アプリにContentResolversとすべてのクエリを実装させるのではなく、コンテンツプロバイダの一部として実装し、IntentService経由で検索をディスパッチしました。

一時テーブルへの単一のカーソルを取得してから、サービスインテントを使用して、他のすべてのコンテンツリゾルバクエリを実行し、基礎となる一時テーブルに移入します。インテントサービスの1つで時間がかかると、ユーザーは実際に気付くことはありません。

問題を解決したようです。

関連する問題