2013-03-12 76 views
1

我正在使用AsyncTask发送一些消息到服务器。这个AsynTask是定义在一个不同的类(CommTask.java)从主要活动类。 插座使用,从weberknecht一个网页套接字,在的AsyncTask的doInBackground方法创建,并且我在CommTask.java一个公共方法(SendDataToServer),即在主活动使用通过CommTask.java类中的实例。android.os.NetworkOnMainThreadException当我使用AsyncTask和HTTPS

我使用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 apears。

有什么想法?为什么会发生这种情况?

如果你需要看看在代码中看到这一点:

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) 
+0

请发布包含您的异常的整个Java堆栈跟踪。 – CommonsWare 2013-03-12 12:54:51

+0

请阅读更多关于AsyncTasks的信息,并查看一些在线示例。你需要使用asynctask.execute()来运行一个asynctask。你不能只在你的任务中调用函数,并期望它们在后台运行。 – 2013-03-12 12:57:43

+0

您在CommTask中的公开方法是从主要步骤的主要活动中调用的。 – njzk2 2013-03-12 12:59:42

回答

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版本的应用程序 被允许在其主要事件循环线程上进行联网,但极不鼓励。

+0

它的工作!但它似乎更像是解决方案,而不是解决方案? 在将答案标记为解决方案之前,我想要更多的意见,如果没有人说什么,我会做。 顺便说一句,当你说onStart()时,我认为你的意思是onExExecute()方法,对吧? – Javi 2013-03-12 13:44:10

+0

我编辑了我的文章,可以阅读它;) – StephaneT 2013-03-15 09:42:11

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方法开始它?

Here是关于这个问题的一篇合理的文章。如果你需要更多的帮助,请告诉我,因为没有多少事情可以继续下去。

+0

是的,我喜欢。我将编辑主帖以清楚说明。 我会看看你的链接,谢谢! – Javi 2013-03-12 13:05:48

1

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

堆栈跟踪表示你没有做你声称要做的事情。您没有使用AsyncTask。相反,从onClick()方法中,您调用CommTask类上的静态方法SendDataToServer(),并且该静态方法正在执行网络I/O。由于onClick()将在主应用程序线程上调用,并且由于您未在此工作中使用AsyncTask或任何其他后台线程,因此SendDataToServer()及其网络I/O正在主应用程序线程上进行。

+0

嗯......我只是把SendDataToServer()放在OnClick()方法中,因为我想加快调试过程。最初的异常,也就是android.os.NetworkOnMainThreadException,当位置管理器有一个更新时,位置管理器被另一个按钮上的另一个onClick()按钮激活。 – Javi 2013-03-12 16:49:19

+0

您可以在这里看到两个SendDataToServer()调用, https://github.com/Javi44/LocAALTOn/blob/WebSockets-Gottox/src/com/android/locaalton/LocAALTOnActivity.java 在行200中是一个我已经用来测试错误,并且在第338行中,是最初引起错误的那个错误。 如果不使用CommTask实例调用方法,那么如何使用AsyncTask?一旦它已经被初始化。我应该每次创建一个新的AsyncTask来发送一些东西吗? – Javi 2013-03-12 16:54:10

+0

@Javi:“我应该每次创建一个新的AsyncTask来发送一些东西吗?” - 可能是。 – CommonsWare 2013-03-12 20:23:12