もう非同期処理では、あたりまえなのだろうが、まとめておかないとすぐに忘れる。
AsyncTaskLoader | Android Developers
目次
1. Thread と AsyncTask
2. AsyncTaskLoader の利点
3. LoaderManager の利用
4. よくある間違いと回避法
5. 基本的な Loader の実装
6. いろいろな Loader の使用例
7. データベースと CursorLoader
8. Loader の弱点を克服する
1. Thread と AsyncTask
まずは、非同期処理ではおなじみのThread。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
final Handler handler = new Handler(new Handler.Callback() { | |
@Override | |
public boolean handleMessage(Message msg) { | |
switch(msg.what) { | |
case RESULT_WHAT: | |
handleResult((Result) msg.obj); | |
return true; | |
} | |
return false; | |
} | |
}); | |
Thread thread = new Thread(new Runnable() { | |
@Override | |
public void run() { | |
Result result = doStuff(); | |
if (isResumed()) { | |
handler.sendMessage(handler.obtainMessage(RESULT_WHAT, result)); | |
} | |
} | |
}); | |
thread.start(); | |
めんどくさいことがいくつかある。
- メインスレッドに結果を戻す必要がある。
- 手動でキャンセルしなければならない。
- スレッドをプールしたければ独自実装しなければならない。
でそこらに対応した AsyncTask。以下の特徴をもつ。
- 結果をメインスレッドに送ってくれる。
- スケジュールは管理されている。
- キャンセル処理も可能。
- 進行状況が取得できる。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
private class DownloadFilesTask extends AsyncTask<Void, Integer, Result> { | |
@Override | |
protected void onPreExecute() { | |
// Something like showing a progress bar | |
} | |
@Override | |
protected Result doInBackground(Void... params) { | |
Result result = new Result(); | |
for (int i = 0; i < STEPS; i++) { | |
result.add(doStuff()); | |
publishProgress(100 * i / STEPS); | |
} | |
return result; | |
} | |
@Override | |
protected void onProgressUpdate(Integer... progress) { | |
setProgressPercent(progress[0]); | |
} | |
@Override | |
protected void onPostExecute(Result result) { | |
handleResult(result); | |
} | |
} |
これの問題点。
アクティビティがdestroyedしたときでもキャンセルできるようにそれぞれのAsyncTaskの参照を保持しておく必要がある。
メモリーリーク: エンクロージングActivityがdestoryされても、AsyncTaskが実行されている間は、そのActivityに参照を保持している。
結果が返却されたあと、Activityが再作成(orientation change)されるとその結果が失われる。
AsyncTaskのスケジューリングは Androidのバージョンによって異なる。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
1.6 以前は、シングルスレッドで順番に実行される | |
1.6 から 2.3、スレッドプールで並列に実行される。 | |
3.0 以降、デフォルトで以前の動作に戻る。スレッドプール利用はexecuteOnExecutor()で。 | |
今どきの端末ではデフォルトでは並列実行されない。 | |
*/ | |
public class ConcurrentAsyncTask { | |
public static void execute(AsyncTask as) { | |
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) { | |
as.execute(); | |
} else { | |
as.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); | |
} | |
} | |
} |
そして、今どきは AsyncTaskLoader。
(→ 「2.AsyncTaskLoader の利点」につづく )
関連ワード: Android・今さら聞けない・開発・AsyncTask・AsyncTaskLoader・Thread・非同期