facebook twitter hatena line email

Android/非同期処理/asynctask/基本

提供: 初心者エンジニアの簡易メモ
移動: 案内検索

注意:AsyncTaskはAndroid11から非推奨となったので非同期処理は以下推奨。

android/非同期処理/HandlerRunnable [ショートカット]

asynctaskとは

バックエンドで同期処理を行う。 例えば、ファイルを連続ダウンロードさせて、進捗ダイアログを出すときなどに使う。

サンプル

  • AsyncTestActivity.java
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
public class AsyncTestActivity extends Activity implements OnClickListener {
 final String TAG = "AsyncTestActivity";
 @Override
 public void onCreate(Bundle savedInstanceState) {
   super.onCreate(savedInstanceState);
   setContentView(R.layout.main);
   ((Button)findViewById(R.id.button1))
     .setOnClickListener(this);
 }
 @Override
 public void onClick(View v) {
   if (v.getId() == R.id.button1){
     MyAsyncTask sync = new MyAsyncTask(this);
     sync.setActivity(this);
     sync.setHoge("test");
     sync.execute("http://yahoo.co.jp", "http://google.co.jp", "http://www.msn.com");
   }
 }
}
  • MyAsyncTask.java
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnCancelListener;
import android.os.AsyncTask;
import android.util.Log;
public class MyAsyncTask extends AsyncTask<String, Integer, Long>
 implements OnCancelListener {
 private final String TAG = "MyAsyncTask";
 private ProgressDialog mDialog;
 private Context mContext;
 private Activity mActivity;
 private String hoge;
 public MyAsyncTask(Context context) {
   this.mContext = context;
 }
 public void setActivity(Activity activity) {
   mActivity = activity;
 }
 public void setHoge(String hoge) {
   this.hoge = hoge;
 }
 @Override
 protected void onPreExecute() {
   Log.d(TAG, "onPreExecute");
               if (mActivity == null) return;
   mDialog = new ProgressDialog(mContext);
   mDialog.setTitle("Please wait");
   mDialog.setMessage("Loading data...");
   mDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
   mDialog.setCancelable(true);
   mDialog.setOnCancelListener(this);
   mDialog.setMax(100);
   mDialog.setProgress(0);
   mDialog.show();
 }
 @Override
 protected Long doInBackground(String... urls) {
   Log.d(TAG, "hoge" + this.hoge);
   int count = urls.length;
   try {
     for (int i = 0; i < count; i++) {
       Log.d(TAG, "url=" + urls[i]);
       if (isCancelled()) break;
       Thread.sleep(1000);
       publishProgress((i+1) * 100 / count);
     }
   } catch (InterruptedException e) {
     Log.d(TAG, "InterruptedException in doInBackground");
   }
   return 123L;
 }
 @Override
 protected void onProgressUpdate(Integer... values) {
   Log.d(TAG, "onProgressUpdate=" + values[0]);
               if (mDialog == null) return;
   mDialog.setProgress(values[0]);
 }
 @Override
 protected void onCancelled() {
   Log.d(TAG, "onCancelled");
               if (mDialog == null) return;
   mDialog.dismiss();
 }
 @Override
 protected void onPostExecute(Long result) {
   Log.d(TAG, "onPostExecute=" + result);
               if (mDialog == null) return;
   mDialog.dismiss();
 }
 public void onCancel(DialogInterface dialog) {
   Log.d(TAG, "Dialog onCancell... calling cancel(true)");
   this.cancel(true);
 }
}
  • res/layout/main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
   android:orientation="vertical"
   android:layout_width="match_parent"
   android:layout_height="match_parent"
   >
<Button
   android:id="@+id/button1"
   android:layout_width="match_parent"
   android:layout_height="wrap_content"
 android:text="text">
   </Button>
</LinearLayout>

以下エラー対応方法

android.view.WindowManager$BadTokenException: Unable to add window -- token null is not valid; is your activity running?

new MyAsyncTask(this);のところをactivity由来のcontextであるthisで渡せばok。

もしくはProgressDialogのところにだけactivityのインスタンスを入れる。

参考:https://qiita.com/le_skamba/items/455d5c37f7a2e853bc67