我正在使用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.NetworkOnMainThreadExceptionapears。
知道吗?为什么会发生这种情况?
如果您需要查看代码,请参阅以下内容:
https://github.com/Javi44/LocAALTOn/tree/WebSockets-Gottox/src/com/android/locaalton
编辑:
此处为完整错误堆栈:
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)
放入
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执行之前(,它将被解决!
[EDIT]更多解释:
来自谷歌文档:
当应用程序尝试执行其主线程上的网络操作。这只是为了针对Honeycomb SDK或更高版本的应用程序。应用程序针对早期版本的SDK允许在其主事件循环线程,但这是非常不鼓励的。
在这里试试我的答案,
https://stackoverflow.com/a/9104893/557179
您的问题是网络请求是在主线程上完成的。
知道吗?为什么会发生这种情况?
堆栈跟踪表明您没有执行您声称正在执行的操作。您没有使用AsyncTask
。相反,从onClick()
方法,您在CommTask
类上调用一个静态SendDataToServer()
方法,而该静态方法正在执行网络I/O。由于onClick()
将在主应用程序线程上调用,并且由于您没有使用AsyncTask
或任何其他后台线程进行此工作,因此SendDataToServer()
及其网络I/O将在主程序线程上进行。
"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
方法启动它?
这是一篇关于这个问题的合理文章。如果你需要更多的帮助,请告诉我,因为没有太多的事情要做。
可能不是您的问题,但您是否通过了证书?
http://developer.android.com/reference/javax/net/ssl/HttpsURLConnection.html
接受Android 上HTTPs的证书