目次へ
Viewの描画に関する処理は、UIスレッド(メインスレッド)で行う必要があります。
別のスレッドで何かを実行し、その途中、あるいは、別のスレッドでの処理が終わってから、UIスレッドで描画を行いたい場合には、AsyncTaskが便利です。
AsyncTaskの使い方は、Swingの、SwingWorkerの使い方と似ています。
また、Androidには、UIスレッド以外のスレッドから描画ができる特別なSurfaceViewというViewもあります。
■■■■サンプル■■■■
下のサンプルは、Activityが作成されると、onCreateメソッドの中でAsyncTaskを継承したクラスのインスタンスを作成し、スタートさせています。AsyncTaskには、次のようなメソッドがあるので、オーバーライドして使います。
- doInBackground⑤
UIスレッドとは、別のスレッドで実行されるのでViewの描画などはできません - onPostExecute⑦
doInBackgroundが終わると、UIスレッドで実行されるので、Viewの描画などが行えます - onProgressUpdate⑧
doInBackgrounからpublishProgressを呼び出す⑥と実行され、UIスレッドで実行されます
また、④を見ると、ジェネリックで次のように型が3つ指定されています。
AsyncTask<Object, String, Integer>
この3つの型を①、②、③とすると、各メソッドの引数に対応します。
- ① doInBackgroundの引数。
⑤のように、引数に...を書くのは、可変個引数の意味で、ここでは、引数があってもなくてもいいという意味で使っています。
このクラスのインスタンスを作りexecuteメソッドを呼び出すとdoInBackgroundが呼び出されるため、execute呼び出し時にdoInBackgroundに渡したいものを渡しますが、 この例では、doInBackgroundに何も渡すものがないので、execute()として呼び出しています。
- ② onProgressUpdateの引数。
⑥でpublishProgressを呼び出すと、onProgressUpdateが呼び出されるため⑥の引数が②の型となります。
また、publishProgressが呼び出されるたびに、すぐにonProgressUpdateが呼び出されるとは限らず、複数回のpublishProgress呼び出しに対して、onProgressUpdateが1回にまとめられることがあるため、複数回の引数が可変個引数として、受け取れるようになっています。
例では String... values となっています。 - ③ onPostExecuteの引数
doInBackgroundが終了すると、その戻り値を引数としてonPostExecuteが呼び出されますので、doInBackgroundの戻り値もこの型となります。
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 次の2行で別スレッドでの実行が始まる
B b = new B();
b.execute(); //①の型の引数を渡すが可変個引数なので無でもOK
}
//① ② ③
class B extends AsyncTask<Object, String, Integer> { //④
//①
protected Void doInBackground(Object... params) { //⑤
for(int i=0; i<10; i++) {
publishProgress("i=" + i); //⑥
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//③
return new Integer(13);
}
//③
protected void onPostExecute(Integer i) { //⑦
Toast.makeText(MainActivity.this,i+"で終わった",
Toast.LENGTH_SHORT).show();
}
//②
protected void onProgressUpdate(String... values) {//⑧
for(String v:values) {
Toast.makeText(MainActivity.this, v,
Toast.LENGTH_SHORT).show();
}
}
}
}
|
にほんブログ村
0 件のコメント:
コメントを投稿