最初から、昔ながらの方法で、標準のAsyncTask / Loadersメソッドについて説明し、使用しないほうがよい理由を説明します。 次に、この問題を解決するための高度な方法について説明します。
AsyncTaskの最も単純なソリューション
長所:
1.わかりやすい。
2.すぐに使用できるソリューション。
短所:
1.画面を反転するときのメモリリーク-古いアクティビティはタスクが完了するまで破棄されず、結果は古いアクティビティに含まれます。ほとんどの場合、例外をキャッチします。
2.エラー処理なし。
3.システムがアプリケーションを破棄することを決定するとすぐに、長時間の操作が中断されます(たとえば、最小化した場合)。
コード例:
requestDataTask = new AsyncTask<Void, Void, JSONObject>() { @Override protected JSONObject doInBackground(Void... params) { // Exception. ( ) final String requestResult = apiService.getData(); final JSONObject json = JsonUtils.parse(requestResult); lruCache.cacheJson(json); return json; } };
最新のソリューション- ローダー
AsyncTaskと同じですが、1つだけ違います。画面を反転すると、新しいアクティビティで結果を取得できます。 しかし、2番目と3番目の問題はまだ存在します。 Googleはローダーの使用を推奨していますが、これを行うことはお勧めしません。 多くの定型コードを作成する必要があります。
あなたはここで例を見ることができます 、またはあなたは私を信じてローダーを使用しないでください。 これらのローダーは非常に冗長なので、ここではコードをコピーしません。
そして今、私の意見では最高のソリューション-Robospice
長所:
1. Robospiceは、サービス中のすべての操作を実行します。 つまり、アクティビティが破棄されても、タスクは引き続き実行されます。 長いタスクに最適なソリューション。
2.エラーを処理する方法があります。
3.キャッシュリクエスト、 Retrofitとの統合。
しかし、すべてがそれほどバラ色ではありません...欠点もあります:
1.タスクが実行されているかどうかを確認する方法はありません。これは私にとって非常に重要なことです。 この問題の解決策を備えたgithubにリクエストプールがあります- #383 。 必要な人は誰でもこのフォークを使用してください。
2.世界で最も便利なAPIではありませんが、機能します。
コード例:
spiceManager.execute(new SpiceRequest<String>(String.class) { @Override public String loadDataFromNetwork() throws Exception { Thread.sleep(1000);// return "It works!!!!"; } }, "key", DurationInMillis.ALWAYS_RETURNED, new RequestListener<String>() { @Override public void onRequestFailure(SpiceException spiceException) { } @Override public void onRequestSuccess(String s) { } });
注目すべきソリューション-RxJava
さまざまな機能を備えた優れたソリューションです。Habrの出版物「Reactive programming for Android」で詳細を読むことができます。
簡単に言えば、エラー処理、アクティビティ/フラグメントライフサイクルのサポートがあります。 しかし、(ロボスパイスとは異なり)長時間の操作には適していないことに加えて、個人的にそれを処理することは個人的に困難であり、それでも全体の考えを理解していないようです。
自分の自転車-Slige Task
長所:
1.わかりやすい AsyncTaskに基づいています。
2.エラー処理があります。
3.ライフサイクルアクティビティをサポートします。
4. Apiはもう少し快適です。
5.タスクが実行されているかどうかを簡単に確認できます。
短所:
1. RxJavaとは異なり、乏しい機能。
2.長いタスクには適していません(Robospiceを参照)。
コード例:
new SligeTask<String,Integer,String>((notifier, strings) -> { try { Thread.sleep(1000); return "executed successfully!!!"; } catch (InterruptedException e) { notifier.publishError(e); // ErrorListener return null; } },LOADER_ID) .setPreExecuteListener(() -> setLoading(true)) .setResultListener(this) .setErrorListener(this) .setCancelListener(this) .setDefaultCallbackLimiter(this) // , activity .execute();
おわりに
結論として、私は要約したいと思います。 個人的には、タスクが長くなく、キャッシングを必要としない場合、プロジェクトでRobospiceとSligeTaskフォークを使用します。 好きなものを自由に選択できます。
はい、もちろん、すべてではありません(多くのライブラリがあります)。 最も人気のあるソリューションを確認しました。 ここでは、他の人の束を見つけることができます。
使用するライブラリとその理由をコメントに記入してください。
誰かがコード例でラムダに気付いたが、それが何で、どのように、そしてなぜわからない場合、 このプロジェクトに注意を払ってください。