Android

[Android] AsyncTask による非同期処理

AsyncTask は、時間のかかる処理を別スレッドで行い、その結果出力を UI スレッドで行うことができる。

Android では、バージョン3.0以降、UI スレッドでの通信処理をするとアプリが落ちる。別スレッドで通信処理を行い、結果を UI スレッドで行う AsyncTask と組み合わせることが必要となってくる。この記事では、メモを兼ねて、AsyncTask を使用した簡単なサンプルコードを紹介する。

動作環境:Android Studio (I/O Preview) AI-130.687321, Android バージョン 4.0.4

サンプルコード

以下に、AsyncTask を用いた簡単なサンプルコードを示す。

「非同期処理を実行」ボタンをタップすると、非同期処理が走る。この間、UI スレッドが固まっていないことを確認するために、適当なボタンを用意している。処理実行中、そのボタンはタップ可能。非同期処理が終了後、textView に、文字列が表示される。

package com.example.myapplication;

import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.Menu;
import android.view.View;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.TextView;

public class MainActivity extends Activity {

    TextView textView;
    Button button1, button2;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        LinearLayout linearLayout = new LinearLayout(this);
        linearLayout.setOrientation(LinearLayout.VERTICAL);
        setContentView(linearLayout);

        textView = new TextView(this);
        linearLayout.addView(textView);

        button1 = new Button(this);
        button1.setText("非同期処理を実行");
        button1.setOnClickListener(new SampleClickListener());
        linearLayout.addView(button1);

        button2 = new Button(this);
        button2.setText("処理中にタップ可能");
        linearLayout.addView(button2);
    }

    class SampleClickListener implements View.OnClickListener
    {
        public void onClick(View view)
        {
            AsyncTask<Void, Void, String> task = new AsyncTask<Void, Void, String>() {
                @Override
                protected String doInBackground(Void... voids) {
                    // 別スレッド
                    try {
                        Thread.sleep(1000);	// 時間のかかる処理(通信処理とか)
                        return "Thread Success!";
                    } catch (InterruptedException exception) {
                        return "Thread Failed!";
                    }
                }

                @Override
                protected void onPostExecute(String result) {
                    // UIスレッド
                    textView.setText(result);
                }
            };
            task.execute(); // 実行
        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }
    
}

AsyncTask

AsyncTask クラスから task というオブジェクトを作成する。その作成時に、doInBackground というメソッドと onPostExecute メソッドをオーバーライドしている。その後、task.execute() でその処理内容をスタートさせる。

doInBackground メソッド内では、UI スレッド以外で処理したいものを記述する(非同期処理になる)。doInBackground が終了した次に、onPostExecute メソッドが呼ばれる。onPostExecute は、UI スレッドで処理が実行されるので、UI の更新作業が行える。このサンプルコードでは、textView に doInBackground からの返り値を表示させている。