从另一个线程写入套接字时发生致命异常

时间:2011-09-04 20:30:22

标签: android

我在两个机器人之间设置了一个套接字连接,我可以来回发送数据没有问题。但是,在服务器端,我设置了ContentObserver,以便在联系人发生更改时收到通知。

我收到了通知,但是当我尝试向客户端发送消息时,联系人已经发生了变化,我得到了一个致命的例外。内容观察者代码是

public class ContactWatcher extends ContentObserver {
   public ContactWatcher( Handler h ) 
   {
      super( h );
   }
   public void onChange(boolean selfChange) 
   { 
   if(!ConnectionManager.devices[0].matches("Null"))
   {
     ConnectionManager.sendMessage(MessageNames.CONTACT_UPDATE, 0);
   }
}

我到了sendMessage代码,但是当它尝试写入套接字时,程序崩溃了LogCat输出

09-04 16:00:50.880: ERROR/AndroidRuntime(958): FATAL EXCEPTION: main
09-04 16:00:50.880: ERROR/AndroidRuntime(958): android.os.NetworkOnMainThreadException
09-04 16:00:50.880: ERROR/AndroidRuntime(958):     at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1077)
09-04 16:00:50.880: ERROR/AndroidRuntime(958):     at dalvik.system.BlockGuard$WrappedNetworkSystem.write(BlockGuard.java:290)
09-04 16:00:50.880: ERROR/AndroidRuntime(958):     at org.apache.harmony.luni.net.PlainSocketImpl.write(PlainSocketImpl.java:462)
09-04 16:00:50.880: ERROR/AndroidRuntime(958):     at org.apache.harmony.luni.net.SocketOutputStream.write(SocketOutputStream.java:55)
09-04 16:00:50.880: ERROR/AndroidRuntime(958):     at java.io.OutputStreamWriter.flush(OutputStreamWriter.java:165)
09-04 16:00:50.880: ERROR/AndroidRuntime(958):     at java.io.BufferedWriter.flush(BufferedWriter.java:129)
09-04 16:00:50.880: ERROR/AndroidRuntime(958):     at java.io.PrintWriter.flush(PrintWriter.java:270)
09-04 16:00:50.880: ERROR/AndroidRuntime(958):     at java.io.PrintWriter.println(PrintWriter.java:491)
09-04 16:00:50.880: ERROR/AndroidRuntime(958):     at java.io.PrintWriter.println(PrintWriter.java:603)
09-04 16:00:50.880: ERROR/AndroidRuntime(958):     at com.gigaset.homepanel.ConnectionManager.sendMessage(ConnectionManager.java:151)
09-04 16:00:50.880: ERROR/AndroidRuntime(958):     at com.gigaset.homepanel.ContactWatcher.onChange(ContactWatcher.java:19)
09-04 16:00:50.880: ERROR/AndroidRuntime(958):     at android.database.ContentObserver$NotificationRunnable.run(ContentObserver.java:43)
09-04 16:00:50.880: ERROR/AndroidRuntime(958):     at android.os.Handler.handleCallback(Handler.java:587)
09-04 16:00:50.880: ERROR/AndroidRuntime(958):     at android.os.Handler.dispatchMessage(Handler.java:92)
09-04 16:00:50.880: ERROR/AndroidRuntime(958):     at android.os.Looper.loop(Looper.java:132)
09-04 16:00:50.880: ERROR/AndroidRuntime(958):     at android.app.ActivityThread.main(ActivityThread.java:4025)
09-04 16:00:50.880: ERROR/AndroidRuntime(958):     at java.lang.reflect.Method.invokeNative(Native Method)
09-04 16:00:50.880: ERROR/AndroidRuntime(958):     at java.lang.reflect.Method.invoke(Method.java:491)
09-04 16:00:50.880: ERROR/AndroidRuntime(958):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:841)
09-04 16:00:50.880: ERROR/AndroidRuntime(958):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:599)
09-04 16:00:50.880: ERROR/AndroidRuntime(958):     at dalvik.system.NativeStart.main(Native Method)

1 个答案:

答案 0 :(得分:1)

NetworkOnMainThreadException课程的Android SDK文档非常清晰且易于理解。它声明当您尝试在主UI线程上执行网络操作时,它会在Honeycomb上抛出。

修复当然是在后台线程中运行网络操作。通过在构造ContentObserver时为该线程传递处理程序,可以将ContentObserver与其他线程关联。

或者,您可以直接生成新线程,或将runnable发布到不同线程上的处理程序。

如果你真的想在主线程上运行网络操作,你应该能够通过StrictMode apis禁用该异常(不推荐)