目次へ
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(); } } } } |
にほんブログ村