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