非同期処理を行う (基本)

非同期処理を行うには Handler を利用する方法もあるが、

Android SDK1.5 からサポートされている AsyncTask を利用するのが便利。

まずは以下のような TextView と Button が設置されているレイアウトを作成します。

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout android:orientation="vertical"

android:layout_width="fill_parent"

android:layout_height="fill_parent"

xmlns:android="http://schemas.android.com/apk/res/android">

<TextView android:id="@+id/textView"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:text="" />

<Button android:id="@+id/button1"

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:text="スレッド処理" />

</LinearLayout>

次に AsyncTask を継承した非同期(スレッド)処理用のクラスを新規に作成します。

package technoute.site.com.google.sites.sample.thread;

import android.app.Activity;

import android.os.AsyncTask;

import android.widget.TextView;

/*

* AsyncTask<型1, 型2,型3>

*

* 型1 … Activityから非同期(スレッド)処理へ渡したい変数の型

* ※ Activityから呼び出すexecute()の引数の型

* ※ doInBackground()の引数の型

*

* 型2 … 進捗度合を表示する時に利用したい型

* ※ onProgressUpdate()の引数の型

*

* 型3 … バックグラウンド処理完了時に受け取る型

* ※ doInBackground()の戻り値の型

* ※ onPostExecute()の引数の型

*

* ※ それぞれ不要な場合は、Voidを設定すれば良い

*/

public class AsyncTaskNoProgressThread extends AsyncTask<Void, Void, String> {

private Activity m_Activity;

/*

* コンストラクタ

*

* @param activity: 読み出し元Activity

*/

public AsyncTaskNoProgressThread(Activity activity) {

// 呼び出し元のアクティビティを変数へセット

this.m_Activity = activity;

}

/*

* バックグラウンドで実行する処理

*

* @param params: Activityから受け渡されるデータ

* @return onPostExecute()へ受け渡すデータ

*/

@Override

protected String doInBackground(Void... params) {

String ret = "";

try {

// Sleep処理(例:HTTP通信)

Thread.sleep(1000);

// Sleep処理(例:HTTP解析/画像変換とか)

Thread.sleep(1000);

// 取得してきた文字列・画像などをreturnでonPostExecuteへ渡す

ret = "読み込み完了!";

} catch (InterruptedException e) {

e.printStackTrace();

}

return ret;

}

/*

* メインスレッドで実行する処理

*

* @param param: doInBackground()から受け渡されるデータ

*/

@Override

protected void onPostExecute(String param) {

// 読み出し元Activityに設置してあるTextViewを取得

TextView textView = (TextView)this.m_Activity.findViewById(R.id.textView);

// TextViewの文字列をセット

textView.setText(param);

return;

}

}

Activityにてボタンクリック時に先ほど追加した非同期(スレッド)処理クラスを生成し、execute()を呼び出したら完成です。

package technoute.site.com.google.sites.sample.thread;

import android.app.Activity;

import android.os.Bundle;

import android.view.View;

import android.view.Window;

import android.view.View.OnClickListener;

import android.widget.TextView;

public class ActivityMain extends Activity implements OnClickListener {

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

// ActivityへViewをセット

setContentView(R.layout.main);

// 各ボタンのリスナーをセット

this.findViewById(R.id.button1).setOnClickListener(this);

}

/*

* ボタンクリック時の処理

*/

@Override

public void onClick(View v) {

//**********************************************************************

// "スレッド処理" ボタンの場合

//**********************************************************************

if (v.getId() == R.id.button1) {

// Activityに設置してあるTextViewを取得

TextView textView = (TextView)this.findViewById(R.id.textView);

// TextViewの文字列をセット

textView.setText("読み込み開始...");

// 非同期(スレッド)クラスの生成

AsyncTaskNoProgressThread thread = new AsyncTaskNoProgressThread(this);

// 非同期(スレッド)処理の実行

thread.execute();

}

}

}