1

我正在使用AsyncTask向服务器发送一些消息。此 AsynTask定义在与主活动类 不同的类 ( CommTask.java ) 中。使用的套接字,来自 weberknecht 的 websocket,是在 AsyncTask 的 doInBackground方法中创建的,我在 CommTask.java 中有一个公共方法 (SendDataToServer),通过 CommTask.java类的实例在主要活动中使用.

在使用 CommTask 的公共方法之前,我在主活动中初始化实例:

commTask = new CommTask(serverIpAddress, socket, textStatus);
commTask.execute();

当我有数据要发送时,我会打电话给:

commTask.SendDataToServer(...);

当它用于主要活动时,来自 CommTask.java 的公共方法和套接字使用 http 协议

socket = new SocketIO("http://"+this.serverIpAddress+":3000/");

没有例外,但是当它使用 https

 socket = new SocketIO("https://"+this.serverIpAddress+":3000/");

android.os.NetworkOnMainThreadException出现。

任何的想法?为什么会发生这种情况?

如果您需要查看代码,请参阅以下内容:

https://github.com/Javi44/LocAALTOn/tree/WebSockets-Gottox/src/com/android/localton

编辑:

完整的错误堆栈在这里:

03-12 15:14:36.090: W/System.err(27088): android.os.NetworkOnMainThreadException
03-12 15:14:36.100: W/System.err(27088):    at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1118)
03-12 15:14:36.100: W/System.err(27088):    at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl$SSLOutputStream.write(OpenSSLSocketImpl.java:686)
03-12 15:14:36.100: W/System.err(27088):    at java.io.BufferedOutputStream.flushInternal(BufferedOutputStream.java:185)
03-12 15:14:36.100: W/System.err(27088):    at java.io.BufferedOutputStream.flush(BufferedOutputStream.java:85)
03-12 15:14:36.100: W/System.err(27088):    at de.roderick.weberknecht.WebSocketConnection.send(WebSocketConnection.java:165)
03-12 15:14:36.100: W/System.err(27088):    at io.socket.WebsocketTransport.send(WebsocketTransport.java:137)
03-12 15:14:36.100: W/System.err(27088):    at io.socket.IOConnection.sendPlain(IOConnection.java:452)
03-12 15:14:36.100: W/System.err(27088):    at io.socket.IOConnection.emit(IOConnection.java:825)
03-12 15:14:36.100: W/System.err(27088):    at io.socket.SocketIO.emit(SocketIO.java:236)
03-12 15:14:36.100: W/System.err(27088):    at com.android.locaalton.CommTask.SendDataToServer(CommTask.java:137)
03-12 15:14:36.105: W/System.err(27088):    at com.android.locaalton.LocAALTOnActivity$2.onClick(LocAALTOnActivity.java:200)
03-12 15:14:36.105: W/System.err(27088):    at android.view.View.performClick(View.java:4211)
03-12 15:14:36.105: W/System.err(27088):    at android.view.View$PerformClick.run(View.java:17267)
03-12 15:14:36.105: W/System.err(27088):    at android.os.Handler.handleCallback(Handler.java:615)
03-12 15:14:36.105: W/System.err(27088):    at android.os.Handler.dispatchMessage(Handler.java:92)
03-12 15:14:36.105: W/System.err(27088):    at android.os.Looper.loop(Looper.java:137)
03-12 15:14:36.105: W/System.err(27088):    at android.app.ActivityThread.main(ActivityThread.java:4898)
03-12 15:14:36.105: W/System.err(27088):    at java.lang.reflect.Method.invokeNative(Native Method)
03-12 15:14:36.105: W/System.err(27088):    at java.lang.reflect.Method.invoke(Method.java:511)
03-12 15:14:36.105: W/System.err(27088):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1006)
03-12 15:14:36.105: W/System.err(27088):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:773)
03-12 15:14:36.105: W/System.err(27088):    at dalvik.system.NativeStart.main(Native Method)
4

5 回答 5

3

if (Integer.valueOf(android.os.Build.VERSION.SDK_INT) >= 9) {
    try {
        // StrictMode.setThreadPolicy(StrictMode.ThreadPolicy.LAX);
           Class<?> strictModeClass = Class.forName("android.os.StrictMode", true, Thread.currentThread()
                        .getContextClassLoader());
           Class<?> threadPolicyClass = Class.forName("android.os.StrictMode$ThreadPolicy", true, Thread.currentThread()
                        .getContextClassLoader());
           Field laxField = threadPolicyClass.getField("LAX");
           Method setThreadPolicyMethod = strictModeClass.getMethod("setThreadPolicy", threadPolicyClass);
                setThreadPolicyMethod.invoke(strictModeClass, laxField.get(null));
    } 
    catch (Exception e) { }
}

在您的onStart()方法中(或在您的AsyncTask 执行之前),它会解决!

[编辑]更多解释:

来自谷歌的文档:

当应用程序尝试在其主线程上执行网络操作时引发的异常。这仅针对面向 Honeycomb SDK 或更高版本的应用程序抛出。允许以早期 SDK 版本为目标的应用程序在其主事件循环线程上进行网络连接,但非常不鼓励这样做。

于 2013-03-12T13:29:56.540 回答
1

在这里试试我的答案,

https://stackoverflow.com/a/9104893/557179

您的问题是网络请求是在主线程上完成的。

于 2013-03-12T13:30:39.203 回答
1

任何的想法?为什么会发生这种情况?

堆栈跟踪表明您没有做您声称正在做的事情。您没有使用AsyncTask. 相反,从一个onClick()方法中,您正在调用一个类的静态SendDataToServer()方法CommTask,而该静态方法正在执行网络 I/O。由于onClick()将在主应用程序线程上调用,并且由于您没有使用AsyncTask任何其他后台线程来完成这项工作,SendDataToServer()并且它的网络 I/O 正在主应用程序线程上进行。

于 2013-03-12T16:17:36.717 回答
0
"and I have a public method in the CommTask.java, that is used in 
the main activity through an instance from the class CommTask.java"

向我建议您错误地使用了 AsyncTask。您是否使用正确的.execute方法启动它?

是一篇关于这个主题的合理文章。如果您需要更多帮助,请告诉我,因为没有太多工作要做。

于 2013-03-12T12:59:20.757 回答
0

可能不是您的问题,但您是否通过了证书?

http://developer.android.com/reference/javax/net/ssl/HttpsURLConnection.html

在 Android 上接受 HTTPs 证书

于 2013-03-12T13:04:24.130 回答