2011-10-04 81 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

欢迎伙伴,享受:) –