スレッドとAsyncTaskを使用して向きの変更を処理するために、さまざまな方法を試してみました。私は次の解決策に出くわしました:
Attach-detach model:インスタンスを保持しながら、アクティビティをスレッドおよびAsyncTaskにアタッチおよびデタッチします。 (出典: 1 、 2 )
ヘッドレスフラグメントの方法:非UI /ヘッドレスフラグメントを使用して、スレッド関連のすべての操作を実行し、構成の変更時にそのインスタンスを保持します。 (出典: 1 、 2 )
このシナリオを処理する他のアプローチはありますか?推奨される方法は何ですか? Androidドキュメントでどこにも一般的な解決策を見つけることができなかったので、私はこれを求めています。
上記の方法にはいくつかの良い方法がありますが、簡単な説明で要約するとよいでしょう。以下は、httpネットワーキング、非同期作業/スレッド化、およびキャッシングに現在使用されている最も人気のあるライブラリの一部です。
私は現在Otto、Loaders、Volley、Ormlite、およびに基づくネットワークスタックApacheおよびService
s。ネットワークスタックをVolley、Retrofit、そして多分最終的にはRobospice。
私個人的にオットーとボレーにとても似ています
@Produce
能力は最後のイベントを保持し、バスに関心のある新しいサブスクライバーに対してオンデマンドで生成できます。Loaders
、特にAsyncTaskLoader
を試してみませんか?それらは Support Library を通じてpre-Honeycombで利用可能であり、アクティビティ/フラグメントのライフサイクルに完全に一致します。ここに公式の要約があります:
- それらはすべてのアクティビティとフラグメントで利用できます。
- データの非同期読み込みを提供します。
- 彼らはデータのソースを監視し、コンテンツが変更されたときに新しい結果を提供します。
- これらは、構成変更後に再作成されるときに、最後のローダーのカーソルに自動的に再接続します。したがって、データを再クエリする必要はありません。
実際にはRoboSpiceライブラリを使用しています。これは、RequestListenersオブジェクトのみを提供するサービスで実行されます。
最初のアプローチの問題(AsyncTask間で参照を保持する)は、おそらく生成できるメモリリーク AsyncTasksがアクティビティ参照を保持している場合、ガベージコレクションされないため。同じアクティビティを何度も繰り返してヒープサイズをチェックするアプリケーションをプロファイリングするだけで、これに注意してください。ヒープは通常のパラメータで増加するはずです(ガベージコレクションの対象となるオブジェクトが新しいオブジェクトと同時に存続する瞬間があります)が、GCが実行されると、RAM割り当ては最初に割り当てたサイズと同じです。
だから私が何かを勧めなければならないなら、次のことになるでしょう:
APIの呼び出しとフローを管理するアクティビティ(RoboSpiceを使用すると、UIを回転させることができます)RetainInstanceをtrueで使用するFragments内のシンプルな画面。これにより、DTOを直接フラグメントに渡すことができ、最上位のアクティビティで状態を管理するだけで済みます。
AsyncTaskの処理が主な懸念事項である場合、つまり方向が変更されるたびにデータをダウンロードしたくない場合は、次のようにしてみてください-
(1)このように作成する前に値を初期化します..
Boolean Android_hacker = false;
(2)ここで、AsyncTaskクラスでのデータのダウンロードが完了したら、その値をtrueに設定します
Android_hacker = true;
ここでは、モデルとアレイアダプタークラスを利用してすべてのデータを維持します。
(3)向きが変わるたびに、このように確認してください
if( Android_hacker = true ){
// Use your saved instance ..
}else{
// Download data as it is yet not downloaded ..
}
それが役に立てば幸い ..
AsyncTask以外にもさまざまな方法があります。また、ベストプラクティスを見つけようとする場合、AsyncTaskは適切なオプションではありません。 この回答 は、AsyncTaskを使用してはならない理由を説明しています。また、長時間実行されるタスクに対処できるより優れた方法 RoboSpice を使用することをお勧めします。
すでにこのライブラリを使用しており、試してみる価値があると思います。アクティビティのライフサイクルを尊重し(向きの変更)、メモリリークがなく、マルチスレッドをサポートし、結果をキャッシュします...長いリクエストタスクをプラグアンドプラグ解除できますキャッシュを使用する(ただし、キャッシュ以外のリクエストではうまく機能しません)。
しかし、私はGoogleからの良い方法をお勧めします:IntentService
およびBroadcastReceiver
。データの結果を受信するために、方向転換中にブロードキャストを登録および未登録します。すべてのバックグラウンドタスクはIntentServiceで機能し、BroadcastReceiverによってアクティビティにしたいことをすべて通知します。あなたが試すことができる多くの例があります。このようなもの: http://mobile.tutsplus.com/tutorials/Android/android-fundamentals-intentservice-basics/
更新:
こんにちはR4j、私のアプリケーションは静かで複雑です。そして、私は多くの並列ネットワーク呼び出しを行わなければなりません。 IntentServiceによるアプローチは優れていますが、複雑なシナリオには適していません
これは問題ではないと思います。 IntentServiceを使用すると、複雑なタスクも含めて何でも実行できます。並列タスクが必要な場合は、マルチスレッド化されたサービスを検討し、インテントによるアクティビティと通信することができます。サービスとアクティビティの間でインテントを送信することは安全で柔軟です。つまり、Android方法です。
そして、(ファイルのダウンロード、ストリーム、データベースによって)キャッシュしたい場合は、RoboSpice
が最適です。