Androidの非同期処理を試す

Androidアプリでスプラッシュ画面を表示させる方法 - MIRAI THE FUTURE
Androidでスプラッシュ画面を表示する方法を調べていたらHandlerを使った処理が出てきたので、ついでに非同期処理を調べてみました。

別スレッドから画面描画はできない

別スレッドからGUIの状態を変化させるメソッドtext.setText()などを呼び出すと、CalledFromWrongThreadExceptionが発生してアプリは落ちてしまいます。

11-28 14:52:25.179: ERROR/AndroidRuntime(412): android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.

Handlerクラスを使うと、別のスレッドからVIEWに触れるスレッドへ処理を依頼することが出来ます。
そこで別スレッド内でHandlerを生成して、Runnableをpost()してみます。

11-28 15:10:59.899: ERROR/AndroidRuntime(464): java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()

Looper.prepareから呼ばれてないスレッド内部からは、Handlerが生成できないそうです。
Handlerを描画スレッドからfinalで生成するようにしたら、GUIを更新できるようになりました。

AsyncTaskで可読性を向上させる

Handlerを使った処理のコードは入れ子入れ子になるので、可読性が悪くなってしまいます。
下記のページでは、それを解決するAsyncTaskというクラスの利用方法について記載されていました。
throw Life - 初めてのAndroid -第7章 世界との接続-
AsyncTaskの実装クラスからexecute()を呼び出すと、doInBackgroundが開始されます。
その処理の結果はonPostExecute内で受け取ることができます。onPostExecute内の処理はHandler経由になるようで、VIEWを更新することができます。
execute()の引数と結果はジェネリクスで指定ができます。(ParamsとResult)

public class ThreadActivity extends Activity {
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.thread);
		final TextView text = (TextView) findViewById(R.id.TextView01);
		Button button = (Button) findViewById(R.id.Button01);
		button.setOnClickListener(new View.OnClickListener() {

			public void onClick(View v) {
				
				new AsyncTask<Integer, Object, String>(){

					@Override
					protected String doInBackground(Integer... params) {
						Integer integer = params[0];
						
						return String.valueOf(integer);
					}
					
					@Override
					protected void onPostExecute(String result) {
						text.setText(result);
					}
				}.execute(1);
			}
		});

	}
}