なにも考えずにスレッド上で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