【问题标题】:android.os.NetworkOnMainThreadException when I am using AsyncTask and HTTPS当我使用 AsyncTask 和 HTTPS 时出现 android.os.NetworkOnMainThreadException
【发布时间】:2013-03-12 12:54:16
【问题描述】:

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

在使用 CommTask 的公共方法之前,我在 main Activity 中初始化了实例:

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/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)

【问题讨论】:

  • 请发布包含您的异常的整个 Java 堆栈跟踪。
  • 请阅读有关 AsyncTasks 的更多信息并查看一些在线示例。您需要使用 asynctask.execute() 运行 asynctask。您不能只调用任务中的函数并期望它们在后台运行。
  • 您在 CommTask 中的公共方法是从主踏板上的主要活动中调用的。
  • 我已经添加了堆栈和我如何使用 AsyncTask 的解释,我忘了告诉我之前调用了 execute()。

标签: android android-asynctask websocket


【解决方案1】:

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 执行之前)它会解决!

[编辑]更多解释:

来自 Google 的文档:

当应用程序尝试执行 在其主线程上进行网络操作。这只是为了 针对 Honeycomb SDK 或更高版本的应用程序。应用 允许针对较早版本的 SDK 进行联网 主事件循环线程,但强烈建议不要这样做。

【讨论】:

  • 成功了!但这似乎更像是解决方法而不是解决方案,不是吗?在将您的答案标记为解决方案之前,我需要更多的意见,如果没有人说什么,我会这样做。顺便说一句,我想你说的 onStart() 是指 onPreExecute() 方法,对吧?
【解决方案2】:

在这里试试我的答案,

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

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

【讨论】:

    【解决方案3】:

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

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

    【讨论】:

    • 嗯...我只是将 SendDataToServer() 放在 OnClick() 方法中,因为我想加快调试过程。最初的异常,也就是 android.os.NetworkOnMainThreadException,是在位置管理器有更新时引发的,位置管理器是通过另一个按钮的另一个 onClick() 按钮激活的。
    • 您可以在这里看到两个 SendDataToServer() 调用,github.com/Javi44/LocAALTOn/blob/WebSockets-Gottox/src/com/… 在第 200 行是我用来测试错误的那个,在第 338 行是引发错误的那个最初的错误。如果不使用 CommTask 实例调用方法,我该如何使用 AsyncTask?一旦它已经初始化。每次我有东西要发送时,我是否应该创建一个新的 AsyncTask?
    • @Javi:“每次我有东西要发送时,我应该创建一个新的 AsyncTask 吗?” -- 可能是的。
    • 但是,当你创建一个 AsyncTask 时,它会创建一个新线程,即使你调用方法 cancel() 它仍然存在......我要发送很多消息,不是这比从主要活动发送消息更糟糕?
    【解决方案4】:
    "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 是关于该主题的合理文章。如果您需要更多帮助,请告诉我,因为没有太多工作要做。

    【讨论】:

    • 是的,我愿意。我将编辑主要帖子以使其清楚。我会看看你的链接,谢谢!
    【解决方案5】:

    【讨论】:

    • 是的,我在设备上安装了自己的证书颁发机构,我用它来签署服务器密钥,并且手机与服务器连接没有问题。还是谢谢你!
    猜你喜欢
    • 2013-04-18
    • 1970-01-01
    • 2016-02-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多