android.view.ViewRootImpl$CalledFromWrongThreadException

Chitty_Tina發表於2016-08-26
android.view.ViewRootImpl$CalledFromWrongThreadException:
Only the original thread that created a view hierarchy can touch its views.

(只有建立了UI物件的主執行緒才能去修改UI)

解決方案一:

在 Android 不是執行緒安全的, Android 有阻止子執行緒更新 UI 的機制。在 Android 程式設計中,需要在主執行緒之外的一個單獨的子執行緒中進行某些耗時操作,然後更新使用者介面顯示。但是,在主執行緒之外的執行緒中直接更新 UI 顯示的問題是:系統會報這個異常,必須在程式的主執行緒(也就是 UI 執行緒)中進行更新介面顯示的工作。於是我們應該將 UI 的更新交給主執行緒來完成,Android為我們提供了一套訊息處理機制。

實現步驟:
  在 Activity 的 onCreate(Bundle savedinstancestate){} 中建立一個Handler類的例項 mHandler,在這個mHandler 例項的 handleMessage(msg) 方法的回撥方法中呼叫更新介面顯示的方法。例如:

public class ExampleActivity extends Activity {  
    Handler h = null;  
    @override  
    public void onCreate(Bundle savedinstancestate){  
        h = new Handler(){  
            @override  
            public void handleMessage(Message msg){  
                // call update gui method.  
            }  
        };  
    }  
}  

 在其它的函式中,利用 send族或post族函式向這個 mHandler 傳送或郵寄訊息即可。
 如果使用 Handler 後還是會報這個錯,就 把 handleMessage(msg)改成sendMessage(msg) 試試。
 

解決方案二:

利用 activity.runOnUiThread(new Runnable(){}),把更新 UI 的程式碼建立在 runnable 中,然後在需要更新 UI 時,把這個 Runnable 物件傳給 activity.runOnUiThread(runnable) 。 這樣 runnable 對像就能在ui程式中被呼叫。

getActivity().runOnUiThread(new Runnable() {
                    @Override
                    public void run() {

                    }
                });