經常使用的幾種方法簡單歸納有:
- handler.sendMessage();
- handler.post();
- 在activity中能夠 runOnUiThread();
- 在子view中能夠 view.post()android
實現代碼省略比較簡單。ide
android在生成頁面的同時生成一個ViewRootImpl的對象,這個對象負責檢查checkThread線程是不是在主ui線程,當咱們嘗試使用非ui線程更新視圖時,checkThread則拋出異常。oop
//onCreate調用這段 new Thread(new Runnable() { @Override public void run() { titleView.setText("OtherThread"); } }).start();
若是你在onCreate的時候這麼寫,系統不會拋出異常。post
可是若是讓線程睡一會好比ui
new Thread(new Runnable() { @Override public void run() { try { Thread.sleep(200); //睡了就再起不來了 } catch (InterruptedException e) { e.printStackTrace(); } titleView.setText("OtherThread"); } }).start(); 會報錯 @Override protected void onResume() { super.onResume(); new Thread(new Runnable() { @Override public void run() { titleView.setText("OtherThread"); } }).start(); } 這樣寫也不會報錯,綜上總結,就是在view未渲染前不會,渲染後就不能在子線程更新ui了 1. 在一個線程裏邊定義一個Looper Looper.prepare(); //稍微有點兒多,詳細見下文1 2.定義一個處理消息的Handler handler = new Handler() { @Override public void handleMessage(Message msg) { super.handleMessage(msg); //處理邏輯 } }; 3.啓動looper,並開始工做,輪詢消息 Looper.loop(); //詳細見下文 //要中止的話,使用Looper.quit(); 4.在其餘線程將要處理的數據data或回調對象callback以消息Message模式經過Handler發至該消息隊列MessageQueue handler.sendMessage(msg)1 5.Looper的loop()方法會從消息隊列中取到該消息並喚醒處理邏輯 //即loop()方法中的代碼 for (;;) { //顯然這個死循環一直在等待消息到來並處理 Message msg = queue.next(); // 取一條消息 if (msg == null) { return; } msg.target.dispatchMessage(msg); //調用消息綁定的handler執行處理邏輯 //other code.... } 6.handler跳轉到執行處理邏輯的過程 public void dispatchMessage(Message msg) { if (msg.callback != null) { //若是有回調,則調用 handleCallback(msg); } else { if (mCallback != null) { if (mCallback.handleMessage(msg)) { return; } } handleMessage(msg); } } //調用回調方法 private static void handleCallback(Message message) { message.callback.run(); } 當咱們要更新UI的時候,都會用到sendMessage,好比使用runOnUiThread,來看下這個方法 public final void runOnUiThread(Runnable action) { /** *若是當前線程不爲Ui主線程則使用定義好的mHandler */ if (Thread.currentThread() != mUiThread) { mHandler.post(action); } else { action.run(); } } post方法也基本是同樣的都是調用sendMessage public final boolean post(Runnable r) { return sendMessageDelayed(getPostMessage(r), 0); } 原文地址: