2012-04-24 104 views
0

我知道從另一個線程更新UI是被禁止的,所以我試着看看我會從應用程序中得到什麼結果。是的,更新UI組件時應用程序會崩潰,但有一種情況我不明白,應用程序運行良好。從另一個線程更新UI

1)

public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.main); 

     tv = (TextView)findViewById(R.id.textView1); 
     bt = (Button)findViewById(R.id.button1); 

     new Thread(){ //1      
      public void run() {        
       tv.setText("changed");      
     }}.start(); //1 } 
    } 

2)

public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.main); 

     tv = (TextView)findViewById(R.id.textView1); 
     bt = (Button)findViewById(R.id.button1); 

     bt.setOnClickListener(new OnClickListener(){ 

      @Override 
      public void onClick(View arg0) { 
       new Thread(){ //1      
         public void run() {        
          tv.setText("changed");      
        }}.start(); //1 } 
      } 

     }); 


    } 

對不起,我以前我的問題的描述,我想大多數人誤解,所以我改一下這個問題。上面有兩種情況,他們應該給我崩潰的錯誤,因爲都創建新的線程和更新UI組件,但實際上,只有第二種情況下崩潰,但fisrt方案不會崩潰。任何人都知道原因?

+0

runOnUiThread或在UI線程中創建處理程序(例如,將其作爲字段或最終處理程序作爲本地變量),然後使用handler.post。 Runnable將是這些函數的參數,裏面的代碼就是你想在UI線程中做什麼 – 2012-04-24 02:00:09

+0

嗨,謝謝你的回覆。我還不是很清楚你的意思。該功能是否存在於adroid中,或者存在於J2SE中?通常我可以在J2SE中使用這種方式創建新線程,對嗎? – 2012-04-24 02:38:28

+0

我改變了這個問題,可能會更容易理解。 – 2012-04-24 03:37:05

回答

1

檢查此異常

E/AndroidRuntime(7652): FATAL EXCEPTION: Thread-19449 
E/AndroidRuntime(7652): android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views. 
E/AndroidRuntime(7652): at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:4357) 
E/AndroidRuntime(7652): at android.view.ViewRootImpl.invalidateChild(ViewRootImpl.java:802) 
E/AndroidRuntime(7652): at android.view.ViewRootImpl.invalidateChildInParent(ViewRootImpl.java:851) 
E/AndroidRuntime(7652): at android.view.ViewGroup.invalidateChild(ViewGroup.java:4312) 
E/AndroidRuntime(7652): at android.view.View.invalidate(View.java:8603) 
E/AndroidRuntime(7652): at android.view.View.invalidate(View.java:8554) 

UI線程檢查僅在無效(渲染)的時間進行檢查。
所以在創建時(onCreate),沒有問題。

您可以在setText之前添加Thread.sleep(5000),併發生上述異常。

+0

哦,男人,你搖滾!我想你找到了原因。你的答案最有意義。謝謝。 – 2012-04-24 03:40:19

+0

哦,我沒有足夠的聲望投票。你應該大拇指。 – 2012-04-24 03:44:02

+0

哈哈,謝謝。接受我的答案或者如果你喜歡它,就投票。 – 2012-04-24 03:44:03

0

檢查了這一點

private void startthread() { 
anihandler = new Handler() { 

@Override 
public void handleMessage(Message msg) { 
    super.handleMessage(msg); 

    tv.setText("changed"); 
} 

}; 

aniThread = new Thread() { 
    public void run() { 
sleep(1000); 
       anihandler.sendMessage(anihandler 
         .obtainMessage()); 


} 
}; 

aniThread.start(); 
} 
+0

我改變了這個問題,可能會更容易理解。 – 2012-04-24 03:41:51

0

取而代之的線程,使用的AsyncTask對於這種操作的。這一切都描述here和非常容易使用。

+0

我已經改變了這個問題,可能會更容易理解。 – 2012-04-24 03:41:17