Androidの非同期処理について

スポンサーリンク

image.png

AndroidAPIを使ったアプリを開発していた際、非同期処理にハマって苦しんだので、忘れないようにまとめました。いわゆる備忘録。 もし間違っている部分がありましたら教えていただけると嬉しいです。

ざっくりと環境

Mac (High Sierra, バージョン10.13.5) Android Studio 3.1.3

非同期処理とは

非同期処理 = メインスレッド以外の別スレッドに処理を投げること 

Androidアプリで行われる処理は、基本的にメインスレッド(UIスレッドともいう)で行われるよう設計されています。

しかし処理がたくさんあったり、一つの処理に要する時間が長かったりする場合は、それらすべての処理をメインスレッドで行ってしまうとメインスレッドに負担がかかってしまいます。

そこで特定の処理を別スレッドに投げることで、メインスレッドの負担を減らすことができるのです。

各スレッドの役割

しかし、すべての処理を別スレッドに投げれるわけではありません。各スレッドで行える処理の代表例は以下のとおりです。

・メインスレッド:UI操作(例:view・ダイアログなどの表示 ・別スレッド:HTTP通信(例:API使用時)

(※もっと色々あると思います)

別スレッドからUI操作をしたい場合は、Handlerを使ってLooperにお願いする必要があります。

LooperとHandler

メインスレッドの根底にはLooperと呼ばれるものがいます。 メインスレッド内の処理はこのLooperの中でぐるぐる回ってます。 スクリーンショット 2018-06-29 22.57.51.png

前述したとおり、UI操作はすべてLooperがやってくれます。 スクリーンショット 2018-06-29 23.01.55.png

別スレッドは、Looperのループの中に入ることができません。 スクリーンショット 2018-07-01 11.57.08.png

なので、Handlerというものを使って、メインスレッドに処理を依頼します。 スクリーンショット 2018-07-01 11.55.52.png

サンプル

以上を踏まえてサンプルコードを書いてみます。

public class AsyncTestActivity extends Activity {

  private TextView textView;
  private Button button;
  Handler mHandler = new Handler();

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        button      = (Button)findViewById(R.id.button);
        textView    = (TextView)findViewById(R.id.textView);

        button.setOnClickListener(new OnClickListener() {
          @Override
          public void onClick(View v) {
            alternativeThread();
          }
        });
    }

    private void alternativeThread() {
      //新しくスレッドを生成
      new Thread(new Runnable(){
        public void run() {

            /* --- 時間のかかる処理を記述 --- */

            //メインスレッドに処理を依頼
            mHandler.post(new Runnable() {
                public void run() {
                    //ここに書かれた処理はメインスレッドで実行される
                    textView.setText("処理が完了しました。");
                }
            });
        }
      }).start();

    }
}

ボタンが押されたら非同期処理が始まります。非同期処理の内容は1つ目に出てくるrun()のなかに記述します。別スレッドからUI操作をする場合はmHandler.postの中に書きます。

参考URL

https://dev.classmethod.jp/etc/22853/ https://academy.realm.io/jp/posts/android-thread-looper-handler/

にほんブログ村 IT技術ブログへ
にほんブログ村