2011-10-04 27 views
1

我試圖將數據發送到單獨線程中的服務器,並讓它將消息發回給我在主線程中更新UI的Handler。使用Handler從線程更新UI時出錯

我已經爲它發送的第2條消息工作,但後來由於某種原因,我得到一個CalledFromWrongThreadException。

我在下面的代碼中添加註釋以顯示哪些方法有效,哪些方法會彈出。

任何幫助將不勝感謝你。

//Started in onCreate() 
    Thread thread = new Thread(new Runnable(){  
         public void run() { 
          sendFiles(); 
         } 
        }); 

        thread.start(); 

    private void sendFiles(){ 

    if(new File(filePath+"/description.txt").isFile()){ //The messages sent from in this if() work but the others bomb. 
     Message message = progressTextHandler.obtainMessage(); 
     message.obj = (progressText.getText() + "\n Started Sending description.txt\n"); 
     progressTextHandler.sendMessage(message); 

     if(sendToServer(filePath+"/description.txt")){ 
      Message message1 = progressTextHandler.obtainMessage(); 
      message1.obj = (progressText.getText() + "\n Finished Sending description.txt\n"); 
      progressTextHandler.sendMessage(message1); 
     }else{ 
      Message message1 = progressTextHandler.obtainMessage(); 
      message1.obj = (progressText.getText() + "\n Error Sending description.txt\n"); 
      progressTextHandler.sendMessage(message1); 
     } 
    } 

    for(int x = 0; x<getIntent().getExtras().getInt("numOfAudio"); x++){ 
     Message message = progressTextHandler.obtainMessage(); 
     message.obj = (progressText.getText() + "\n Started Sending " + getIntent().getExtras().getString("audio"+String.valueOf(x)) + "\n"); 
     progressTextHandler.sendMessage(message); 

     if(sendToServer(getIntent().getExtras().getString("audio"+String.valueOf(x)))){ 
      Message message1 = progressTextHandler.obtainMessage(); 
      message1.obj = (progressText.getText() + "\n Finished Sending " + getIntent().getExtras().getString("audio"+String.valueOf(x)) + "\n"); 
      progressTextHandler.sendMessage(message1); 
     }else{ 
      Message message1 = progressTextHandler.obtainMessage(); 
      message1.obj = (progressText.getText() + "\n Error Sending " + getIntent().getExtras().getString("audio"+String.valueOf(x)) + "\n"); 
      progressTextHandler.sendMessage(message1); 
     } 

    } 

    for(int k = 0; k<getIntent().getExtras().getInt("numOfBrowsed"); k++){ 
     Message message = progressTextHandler.obtainMessage(); 
     message.obj = (progressText.getText() + "\n Started Sending " + getIntent().getExtras().getString("pic"+String.valueOf(k))+"\n"); 
     progressTextHandler.sendMessage(message); 

     if(sendToServer(getIntent().getExtras().getString("pic"+String.valueOf(k)))){ 
      Message message1 = progressTextHandler.obtainMessage(); 
      message1.obj = (progressText.getText() + "\n Finished Sending " + getIntent().getExtras().getString("pic"+String.valueOf(k))+"\n"); 
      progressTextHandler.sendMessage(message1); 
     }else{ 
      Message message1 = progressTextHandler.obtainMessage(); 
      message1.obj = (progressText.getText() + "\n Error Sending " + getIntent().getExtras().getString("pic"+String.valueOf(k))+"\n"); 
      progressTextHandler.sendMessage(message1); 
     } 

    } 
    for(int l = 0; l<getIntent().getExtras().getInt("numOfStills"); l++){ 
     Message message = progressTextHandler.obtainMessage(); 
     message.obj = ("\n Started Sending " + getIntent().getExtras().getString("still"+String.valueOf(l))+"\n"); 
     progressTextHandler.dispatchMessage(message); 

     if(sendToServer(getIntent().getExtras().getString("still"+String.valueOf(l)))){ 
      Message message1 = progressTextHandler.obtainMessage(); 
      message1.obj = (progressText.getText() + "\n Finished Sending " + getIntent().getExtras().getString("still"+String.valueOf(l))+"\n"); 
      progressTextHandler.dispatchMessage(message1); 
     }else{ 
      Message message1 = progressTextHandler.obtainMessage(); 
      message1.obj = (progressText.getText() + "\n Error Sending " + getIntent().getExtras().getString("still"+String.valueOf(l))+"\n"); 
      progressTextHandler.dispatchMessage(message1);   
     } 

    } 

    for(int m = 0; m<getIntent().getExtras().getInt("numOfVideos"); m++){ 
     Message message = progressTextHandler.obtainMessage(); 
     message.obj = (progressText.getText() + "\n Finished Sending " + getIntent().getExtras().getString("video"+String.valueOf(m))+"\n"); 
     progressTextHandler.dispatchMessage(message); 

     if(sendToServer(getIntent().getExtras().getString("video"+m))){ 
      Message message1 = progressTextHandler.obtainMessage(); 
      message1.obj = (progressText.getText() + "\n Finished Sending " + getIntent().getExtras().getString("video"+String.valueOf(m))+"\n"); 
      progressTextHandler.dispatchMessage(message1); 
     }else{ 
      Message message1 = progressTextHandler.obtainMessage(); 
      message1.obj = (progressText.getText() + "\n Error Sending " + getIntent().getExtras().getString("video"+String.valueOf(m))+"\n"); 
      progressTextHandler.dispatchMessage(message1); 
     } 
    } 

}// end of sendFiles() 



    progressTextHandler = new Handler(){  //my handler that also lives in onCreate() 
     public void handleMessage(Message msg){ 
      progressText.setText((String)msg.obj); 
     } 
    }; 

這是我得到的printStackTrace。

10-03 23:51:20.105: WARN/dalvikvm(5760): threadid=10: thread exiting with uncaught exception (group=0x40018560) 
10-03 23:51:20.144: ERROR/AndroidRuntime(5760): FATAL EXCEPTION: Thread-11 
10-03 23:51:20.144: ERROR/AndroidRuntime(5760): android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views. 
10-03 23:51:20.144: ERROR/AndroidRuntime(5760):  at android.view.ViewRoot.checkThread(ViewRoot.java:2932) 
10-03 23:51:20.144: ERROR/AndroidRuntime(5760):  at android.view.ViewRoot.invalidateChild(ViewRoot.java:642) 
10-03 23:51:20.144: ERROR/AndroidRuntime(5760):  at android.view.ViewRoot.invalidateChildInParent(ViewRoot.java:668) 
10-03 23:51:20.144: ERROR/AndroidRuntime(5760):  at android.view.ViewGroup.invalidateChild(ViewGroup.java:2511) 
10-03 23:51:20.144: ERROR/AndroidRuntime(5760):  at android.view.View.invalidate(View.java:5255) 
10-03 23:51:20.144: ERROR/AndroidRuntime(5760):  at android.widget.TextView.invalidateCursor(TextView.java:3983) 
10-03 23:51:20.144: ERROR/AndroidRuntime(5760):  at android.widget.TextView.spanChange(TextView.java:6797) 
10-03 23:51:20.144: ERROR/AndroidRuntime(5760):  at android.widget.TextView$ChangeWatcher.onSpanAdded(TextView.java:6926) 
10-03 23:51:20.144: ERROR/AndroidRuntime(5760):  at android.text.SpannableStringBuilder.sendSpanAdded(SpannableStringBuilder.java:979) 
10-03 23:51:20.144: ERROR/AndroidRuntime(5760):  at android.text.SpannableStringBuilder.setSpan(SpannableStringBuilder.java:632) 
10-03 23:51:20.144: ERROR/AndroidRuntime(5760):  at android.text.SpannableStringBuilder.setSpan(SpannableStringBuilder.java:535) 
10-03 23:51:20.144: ERROR/AndroidRuntime(5760):  at android.text.Selection.setSelection(Selection.java:74) 
10-03 23:51:20.144: ERROR/AndroidRuntime(5760):  at android.text.Selection.setSelection(Selection.java:85) 
10-03 23:51:20.144: ERROR/AndroidRuntime(5760):  at android.text.method.ArrowKeyMovementMethod.initialize(ArrowKeyMovementMethod.java:268) 
10-03 23:51:20.144: ERROR/AndroidRuntime(5760):  at android.widget.TextView.setText(TextView.java:3003) 
10-03 23:51:20.144: ERROR/AndroidRuntime(5760):  at android.widget.TextView.setText(TextView.java:2883) 
10-03 23:51:20.144: ERROR/AndroidRuntime(5760):  at android.widget.EditText.setText(EditText.java:78) 
10-03 23:51:20.144: ERROR/AndroidRuntime(5760):  at android.widget.TextView.setText(TextView.java:2858) 
10-03 23:51:20.144: ERROR/AndroidRuntime(5760):  at com.vincentjuliano.jreporter.SubmitServer$2.handleMessage(SubmitServer.java:104) 
10-03 23:51:20.144: ERROR/AndroidRuntime(5760):  at android.os.Handler.dispatchMessage(Handler.java:99) 
10-03 23:51:20.144: ERROR/AndroidRuntime(5760):  at com.vincentjuliano.jreporter.SubmitServer.sendFiles(SubmitServer.java:227) 
10-03 23:51:20.144: ERROR/AndroidRuntime(5760):  at com.vincentjuliano.jreporter.SubmitServer.access$4(SubmitServer.java:173) 
10-03 23:51:20.144: ERROR/AndroidRuntime(5760):  at com.vincentjuliano.jreporter.SubmitServer$1$1.run(SubmitServer.java:70) 
10-03 23:51:20.144: ERROR/AndroidRuntime(5760):  at java.lang.Thread.run(Thread.java:1019) 
10-03 23:51:20.167: WARN/ActivityManager(1322): Force finishing activity com.vincentjuliano.jreporter/.SubmitServer 
+0

線程的線程=新主題有用的(新的Runnable(){ 公共無效的run(){ sendFiles();} }); 爲什麼你需要傳遞一個可運行的線程? –

+0

我不知道。我認爲這是應該如何完成的。據我瞭解,你將Runnable傳遞給線程,當你調用thread.start()時,它會在run()中調用函數。我該怎麼做這個? – jln646v

回答

1

的代碼,我認爲這是一個有點晚了,但我會給你我看來non-UI threadUpdating一個的UI:中問題在於你在幾行中使用了handler.dispatchMessage(當你在前面的行中使用了handler.sendMessage時,這是正確的)。

雖然dispatchMessage在調用dispatchMessage方法的同一線程中立即調用處理函數,但sendMessage會在附加到此處理函數的線程中的handleMessage(Message)中接收到消息。

所以,如果你用sendMessage替換那些dispatchMessage,代碼將比使用runOnUiThread更乾淨。

我希望這是有人:)

1

在堆棧跟蹤,它出現的異常是從這樣的事實出現以後,

com.vincentjuliano.jreporter.SubmitServer$2.handleMessage(SubmitServer.java:104) 10-03 

試圖更新的用戶界面,但不是在UI線程上。考慮使用Activity.runOnUiThread()更新用戶界面。使用這個函數,你不需要擔心Handlers和Loopers。

1

爲了從你需要使用activity.this.runOnUiThread()方法,這將執行上UI thread.

Activity_name.this.runOnUiThread(new Runnable() { 

      @Override 
      public void run() { 
       // TODO Auto-generated method stub 

      } 
     }); 
+0

謝謝!我把所有的東西都移動到使用this.runOnUiThread(),它似乎工作得很好。 – jln646v

+0

歡迎夥伴,享受:) –