android.view.ViewRoot$CalledFromWrongThreadException 異常的解決

在android平臺下,進行多線程編程時,經常需要在主線程之外的一個單獨的線程中進行某些處理,然後更新用戶界面顯示。但是,在主線線程之外的線程中直接更新頁面顯示的問題是:系統會報這個異常,android.view.viewroot$calledfromwrongthreadexception: only the original thread that created a view hierarchy can touch its views. (只有原始創建這個視圖層次(view hierachy)的線程才能修改它的視圖(view)。)。

  也就是說必須在程序的主線程(也就是ui線程)中進行更新界面顯示的工作。可以採用下面的方法之一來解決:

解決方案1:在activity.oncreate(bundle savedinstancestate)中創建一個handler類的實例, 在這個handler實例的handlemessage回調函數中調用更新界面顯示的函數。例如:

  

[java] view plaincopy
  1. public class ExampleActivity extends Activity {  
  2.     Handler h = null;  
  3.     @override  
  4.     public void onCreate(Bundle savedinstancestate){  
  5.         h = new Handler(){  
  6.             @override  
  7.             public void handleMessage(Message msg){  
  8.                 // call update gui method.  
  9.             }  
  10.         };  
  11.     }  
  12. }  

  在其它的函數中,利用 send族或post族函數向這個h發送或郵寄消息即可。


解決方案2:利用activity.runonuithread(runnable)

  把更新ui的代碼創建在runnable中,然後在需要更新ui時,把這個runnable對象傳給activity.runonuithread(runnable)。 這樣runnable對像就能在ui程序中被調用。



正確寫法一 : 交由UI Thread處理

[java]   view plain copy
  1. import java.util.Timer;  
  2. import java.util.TimerTask;  
  3. import android.app.Activity;  
  4. import android.os.Bundle;  
  5. public class TestTimer extends Activity {  
  6.     Timer timer = new Timer();  
  7.     TimerTask task = new TimerTask(){  
  8.         public void run() {  
  9.               
  10.             runOnUiThread(new Runnable(){  
  11.             @Override  
  12.             public void run() {  
  13.                 setTitle("hear me?");  
  14.             }});  
  15.             }  
  16.     };  
  17.     public void onCreate(Bundle savedInstanceState) {  
  18.         super.onCreate(savedInstanceState);  
  19.         setContentView(R.layout.main);  
  20.         timer.schedule(task, 10000);  
  21.     }  
  22. }  

 

正確寫法二 :由Handler處理UI 更新。


  1. package com.test;     
  2.     
  3. import java.util.Timer;     
  4. import java.util.TimerTask;     
  5.     
  6. import android.app.Activity;     
  7. import android.os.Bundle;     
  8. import android.os.Handler;     
  9. import android.os.Message;     
  10.     
  11. public class TestTimer extends Activity {     
  12.     
  13.     Timer timer = new Timer();     
  14.     Handler handler = new Handler(){     
  15.     
  16.         public void handleMessage(Message msg) {     
  17.             switch (msg.what) {         
  18.             case 1:         
  19.                 setTitle("hear me?");     
  20.                 break;         
  21.             }         
  22.             super.handleMessage(msg);     
  23.         }     
  24.              
  25.     };     
  26.     TimerTask task = new TimerTask(){     
  27.     
  28.         public void run() {     
  29.             Message message = new Message();         
  30.             message.what = 1;         
  31.             handler.sendMessage(message);       
  32.         }     
  33.              
  34.     };     
  35.     public void onCreate(Bundle savedInstanceState) {     
  36.         super.onCreate(savedInstanceState);     
  37.         setContentView(R.layout.main);     
  38.         timer.schedule(task, 10000);     
  39.     }     
  40. }  

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章