和許多其餘的GUI 庫同樣,Android 的UI 也是線程不安全的。也就是說,若是想要更新應用程序裏的UI 元素,則必須在主線程中進行,不然就會出現異常。瞭解AsyncTask的用法,請參見個人博客:(android高級---->Asynctask的源碼分析)今天咱們就來學習一下有關UI更新的一些知識。html
目錄:java
今天咱們經過一個小案例,來講明更新UI的所有測試內容:項目結構以下android
在子線程中更新UI
1、 在MainActivity.java的onCreate方法中作一些初始化工做,初始化textView
private TextView textView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); textView = (TextView) findViewById(R.id.textView); }
2、 點擊threadUpdateUI按鈕,觸發在子線程中更新UI的事件
// 在子線程中更新UI public void threadUpdateUI(View view) { new Thread(new Runnable() { @Override public void run() { textView.setText("I love you."); } }).start(); }
3、 運行結果以下,說明在子線程中的確不能更新UI
- 日誌打印結果: Only the original thread that created a view hierarchy can touch its views.
- 測試真機崩潰:
用Handler機制實現UI的更新
1、 定義一個Handler,用於接收處理消息
public static final int UPDATE_TEXT = 1; private Handler handler = new Handler() { @Override public void handleMessage(Message msg) { switch (msg.what) { case UPDATE_TEXT: textView.setText("I Love you."); break; default: break; } } }
2、 點擊按鈕,觸發在子線程中發送消息的事件
// 用handler處理上述問題 public void handlerUpdate(View view) { new Thread(new Runnable() { @Override public void run() { Message message = new Message(); message.what = UPDATE_TEXT; handler.sendMessage(message); // 將Message對象發送出去 } }).start(); }
結果正常,textView顯示爲:I love you安全
用AsyncTask機制實現UI的更新
1、 建立一個繼承AsyncTask的內部類,命名爲:MyAsynTask
private class MyAsynTask extends AsyncTask<Void, Void, Void> { @Override protected Void doInBackground(Void... params) { return null; } @Override protected void onPostExecute(Void aVoid) { textView.setText("I love you"); } }
2、 點擊按鈕,建立AsyncTask的實例,並調用execute方法:
// 用AsyncTask處理上述問題 public void asynTask(View view) { MyAsynTask myAsynTask = new MyAsynTask(); myAsynTask.execute(); }
結果正常,textView顯示爲:I love you。async
友情連接
關於AsyncTask類的詳細使用,請參見個人博客 (android高級---->Asynctask的源碼分析)ide