@blog.justoneplanet.info

日々勉強

androidで別スレッドからUIを変更する

メモ。AsyncTaskは別記事で今回はHandler使おうってことで。

■実装

以下のようにすると強制終了する。

import android.app.Activity;
import android.app.ProgressDialog;
import android.os.Bundle;

public class MainActivity extends Activity {
    private ProgressDialog dialog;
    
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        // dialogの生成
        dialog = new ProgressDialog(this);
        dialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
        dialog.setMessage("wait...");
        dialog.show();
        
        // 別スレッド
        new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 10; i++) {
                    updateProgress(i);
                }
                dialog.dismiss();
            }

            private void updateProgress(int i) {
                try {
                    Thread.sleep(1000);
                }
                catch (InterruptedException e) {
                    e.printStackTrace();
                }
                dialog.setMessage(i + " seconds");
            }
        }).start();
    }
}

以下のようにすることで問題なく処理することができる。

import android.app.Activity;
import android.app.ProgressDialog;
import android.os.Bundle;
import android.os.Handler;

public class MainActivity extends Activity {
    private ProgressDialog dialog;
    // Handlerクラスをインスタンス化すると、同スレッドのLooperオブジェクトとメッセージキューに紐付けられる
    Handler handler = new Handler();
    
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        // ダイアログの生成
        dialog = new ProgressDialog(this);
        dialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
        dialog.setMessage("wait...");
        dialog.show();
        
        // 別スレッド
        new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 10; i++) {
                    updateProgress(i);
                }
                dialog.dismiss();
            }

            private void updateProgress(final int i) {
                try {
                    Thread.sleep(1000);
                }
                catch (InterruptedException e) {
                    e.printStackTrace();
                }
                // メッセージキューに処理を投げる => メインのLooperへ
                handler.post(new Runnable() {
                    @Override
                    public void run() {
                        dialog.setMessage(i + " seconds");
                    }
                });
            }
        }).start();
    }
}

Runnableとは

スレッドを作るためのインターフェースで、RunnableインターフェースのrunメソッドをオーバーライドしてThreadのコンストラクタに渡すした時に、Threadクラスのstartメソッドを呼ぶことでrunメソッドが別のスレッドで実行される。

Androidでのメッセージキューの処理は、android.os.Looperとandroid.os.Handlerの2つのクラスが担っている。

コメントはまだありません»

No comments yet.

RSS feed for comments on this post.TrackBack URL

Leave a comment