毎週20130829-Android非同期タスクをまとめます
2913 ワード
Android非同期タスク——AsyncTask
Android開発でよく発生するエラーは、他のスレッドでUI部分を変更し、プログラムが直接エラーになったことです.ついに、表示されるエラーはOnly the original thread that created a view hierarchy can touch its viewです.これはAndroidシステムの制限のためで、他のスレッドはUIにナイフを動かす資格がありません.バックグラウンドタスクがUIと対話する問題を解決するために、私がよく使う方法は、バックグラウンドタスクを処理するスレッドを開き、このスレッドでUIスレッドのHandlerにメッセージを送信し、Handlerがメッセージを処理し、UI要素を修正することです.これはすべての場合に適用される案ではなく、まずThread自体が相対的に重量級で、使いにくいので間違いやすい.次に、1つのメッセージしかない場合がありますが、このメッセージを処理するためにHandlerを使うのは気分が悪いのではないでしょうか.AsyncTaskは,あまり複雑なニーズがない場合に,UIスレッドと容易に対話するために存在する.
AsyncTaskはThreadと似ている点があり、いくつかの方法を継承し、実装する必要があります.AsyncTaskは汎用クラスで、継承時に3つのパラメータタイプ(AsyncTask方法1:abstract Result doInBackground(Params...params)
方法2:void onProgressUpdate(Progress...values)
/**実はpublishProgressメソッドもこのタイプのパラメータですが、このメソッドは自分で書き換える必要はなく、doInBackgroundで呼び出せばOK**/
方法3:void onPostExecute(Result result)
宣言から,メソッド1は抽象的なメソッドであり,サブクラスでは書き直さなければならず,Threadのvoid run()メソッドに少し似ていることがわかる.AsyncTaskに指定した最初のパラメータタイプがそのパラメータタイプです.この方法は1つのパラメータタイプしかありませんが、パラメータの個数は制限されません.異なるタイプの複数のパラメータを入力する必要がある場合は、Paramsを直接Objectに指定することができます.名称からも分かるように,メソッド1はバックグラウンドで実行されるタスクであり,単独のスレッドで実行され,すべての時間のかかるタスクがこのメソッドに頭を突っ込むことになるだろう.なお,その戻り値タイプはAsyncTaskに指定された2番目のパラメータタイプである.
方法2は進捗を更新するためのものであり,UIスレッドで実行すると進捗バーのインデックスを更新するために利用できるので,通常AsyncTaskに指定される2番目のパラメータタイプはInteger型である.
方法3はバックグラウンドタスクが完了してから呼び出され,UIスレッドで実行される.そのパラメータタイプはAsyncTaskに指定された3番目のパラメータタイプであるため、入力されたパラメータがメソッド1の戻り値であることを大胆に推測してみてください.興味のある方はDemoを書いて検証してください.
もう一つの方法は、
方法0:void onPreExecute()
そう、この方法はバックグラウンドタスクを開始する前に呼び出され、UIスレッドでも実行されます.
これらの方法では,方法1のみが単独で開かれたスレッドで実行され,また方法1のみがサブクラスで実現されなければならず,他の方法は必要に応じて書き換えることができることが分かる.次にandroid referenceから切り取った小さな例を示します.AsyncTaskの使用を簡単に示します.
これで大成功だ!AsyncTaskも、プロセスが制御可能で、いつでもキャンセルできるなど、独自の特徴を持っています.
Android開発でよく発生するエラーは、他のスレッドでUI部分を変更し、プログラムが直接エラーになったことです.ついに、表示されるエラーはOnly the original thread that created a view hierarchy can touch its viewです.これはAndroidシステムの制限のためで、他のスレッドはUIにナイフを動かす資格がありません.バックグラウンドタスクがUIと対話する問題を解決するために、私がよく使う方法は、バックグラウンドタスクを処理するスレッドを開き、このスレッドでUIスレッドのHandlerにメッセージを送信し、Handlerがメッセージを処理し、UI要素を修正することです.これはすべての場合に適用される案ではなく、まずThread自体が相対的に重量級で、使いにくいので間違いやすい.次に、1つのメッセージしかない場合がありますが、このメッセージを処理するためにHandlerを使うのは気分が悪いのではないでしょうか.AsyncTaskは,あまり複雑なニーズがない場合に,UIスレッドと容易に対話するために存在する.
AsyncTaskはThreadと似ている点があり、いくつかの方法を継承し、実装する必要があります.AsyncTaskは汎用クラスで、継承時に3つのパラメータタイプ(AsyncTask
方法2:void onProgressUpdate(Progress...values)
/**実はpublishProgressメソッドもこのタイプのパラメータですが、このメソッドは自分で書き換える必要はなく、doInBackgroundで呼び出せばOK**/
方法3:void onPostExecute(Result result)
宣言から,メソッド1は抽象的なメソッドであり,サブクラスでは書き直さなければならず,Threadのvoid run()メソッドに少し似ていることがわかる.AsyncTaskに指定した最初のパラメータタイプがそのパラメータタイプです.この方法は1つのパラメータタイプしかありませんが、パラメータの個数は制限されません.異なるタイプの複数のパラメータを入力する必要がある場合は、Paramsを直接Objectに指定することができます.名称からも分かるように,メソッド1はバックグラウンドで実行されるタスクであり,単独のスレッドで実行され,すべての時間のかかるタスクがこのメソッドに頭を突っ込むことになるだろう.なお,その戻り値タイプはAsyncTaskに指定された2番目のパラメータタイプである.
方法2は進捗を更新するためのものであり,UIスレッドで実行すると進捗バーのインデックスを更新するために利用できるので,通常AsyncTaskに指定される2番目のパラメータタイプはInteger型である.
方法3はバックグラウンドタスクが完了してから呼び出され,UIスレッドで実行される.そのパラメータタイプはAsyncTaskに指定された3番目のパラメータタイプであるため、入力されたパラメータがメソッド1の戻り値であることを大胆に推測してみてください.興味のある方はDemoを書いて検証してください.
もう一つの方法は、
方法0:void onPreExecute()
そう、この方法はバックグラウンドタスクを開始する前に呼び出され、UIスレッドでも実行されます.
これらの方法では,方法1のみが単独で開かれたスレッドで実行され,また方法1のみがサブクラスで実現されなければならず,他の方法は必要に応じて書き換えることができることが分かる.次にandroid referenceから切り取った小さな例を示します.AsyncTaskの使用を簡単に示します.
private class DownloadFilesTask extends AsyncTask<URL, Integer, Long> {
protected Long doInBackground(URL... urls) {
int count = urls.length;
long totalSize = 0;
for (int i = 0; i < count; i++) {
totalSize += Downloader.downloadFile(urls[i]);
publishProgress((int) ((i / (float) count) * 100));
// Escape early if cancel() is called
if (isCancelled()) break;
}
return totalSize;
}
protected void onProgressUpdate(Integer... progress) {
setProgressPercent(progress[0]);
}
protected void onPostExecute(Long result) {
showDialog("Downloaded " + result + " bytes");
}
}
, UI :
new DownloadFilesTask().execute(url1, url2, url3);
これで大成功だ!AsyncTaskも、プロセスが制御可能で、いつでもキャンセルできるなど、独自の特徴を持っています.