June 9, 2012

スレッドからUIを操作する

スレッド(Thread)からAndroidのUIを操作する方法です。

なにも考えずにスレッド上でUI操作してしまうと"CalledFromWrongThreadException"というfatal exceptionが投げられてアプリが強制終了してしまいます。

例)exceptionが発生する失敗例

public class SampleAppActivity extends Activity {
 private final static String TAB = "SampleAppActivity";
 private ProgressBar mProgress;

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

        setContentView(R.layout.main);
        mProgress = (ProgressBar) findViewById(R.id.progress);

        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    Thread.sleep(3000);
                } catch (InterruptedException e) {
                }
                mProgress.setVisibility(View.GONE);
            }
        }).start();
    }
}

これはなぜかというと、AndroidのUIはActivityがもっているUIスレッド上でしか動作しないようになっていて、他のスレッドから操作されると上記のexceptionを投げるようになっています。Androidの仕組みでは、UIの操作はすべてUIスレッドで処理させるように作らなければなりません。そのため他のスレッドからUIの操作を実行する場合は、Handlerというクラスを使って、処理をRunnableオブジェクトとしてUIスレッドにメッセージで送り、UIスレッドがそれを受け取って処理を実行する、というふうに作り替えます。

例)他のスレッドからUIの操作の成功例

public class SampleAppActivity extends Activity {
 private final static String TAB = "SampleAppActivity";
 private Handler mHandler = new Handler();
 private ProgressBar mProgress;

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

        setContentView(R.layout.main);
        mProgress = (ProgressBar) findViewById(R.id.progress);

        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    Thread.sleep(3000);
                } catch (InterruptedException e) {
                }
                mHandler.post(new Runnable() {
                    @Override
                    public void run() {
                        mProgress.setVisibility(View.GONE);
                    }
                });
            }
        }).start();
    }
}

参考:Android Developers:Handler

No comments:

Post a Comment