使用Phonegap 1.6.0进行Facebook登录时出现了NetworkOnMainThreadException异常

7
我正在使用Phonegap 1.6.0和Sencha Touch 1.1创建一个应用程序。最近,在智能手机Android 4.0.4上测试时,我们发现Facebook登录功能无法正常工作。我们使用了位于此处的Phonegap Facebook插件,其中包含Cordova的补丁程序。问题是,一旦我们尝试在具有Android Honeycomb或更高版本的智能手机上登录Facebook,应用程序就会启动NetworkOnMainThreadException,因为不允许在主线程上执行网络操作。这个异常只在Android Honeycomb或以上版本上抛出,这就是为什么我们在2.3.3上没有注意到它的原因。当调用FB.login()并且回调未被触及时,就会抛出该异常。
我已经查看了各种帖子和主题,但都极其模糊。我知道我必须在单独的线程中运行网络操作,但我不确定应该如何做。线程似乎是在Java中进行的,但我根本没有使用任何Java,因此在我编写的代码中进行修改之前,我需要一些帮助。
稍后我将尝试缩小引起异常的部分。感谢您的任何帮助。
错误堆栈:
05-25 15:42:29.018: I/Web Console(3785): Cordova Facebook Connect plugin initialized successfully. at file:///android_asset/www/cdv-plugin-fb-connect.js:24
05-25 15:42:29.120: D/OpenGLRenderer(3785): Flushing caches (mode 0)
05-25 15:42:30.479: D/ConnectPlugin(3785): authorized
05-25 15:42:30.479: D/ConnectPlugin(3785): Bundle[{expires_in=5177550, access_token=censored, code=censored}]
05-25 15:42:30.503: D/AndroidRuntime(3785): Shutting down VM
05-25 15:42:30.503: W/dalvikvm(3785): threadid=1: thread exiting with uncaught exception (group=0x40a671f8)
05-25 15:42:30.511: E/AndroidRuntime(3785): FATAL EXCEPTION: main
05-25 15:42:30.511: E/AndroidRuntime(3785): java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=32665, result=-1, data=Intent { (has extras) }} to activity {com.company.product/com.company.product.productActivity}: android.os.NetworkOnMainThreadException
05-25 15:42:30.511: E/AndroidRuntime(3785):     at android.app.ActivityThread.deliverResults(ActivityThread.java:2980)
05-25 15:42:30.511: E/AndroidRuntime(3785):     at android.app.ActivityThread.handleSendResult(ActivityThread.java:3023)
05-25 15:42:30.511: E/AndroidRuntime(3785):     at android.app.ActivityThread.access$1100(ActivityThread.java:123)
05-25 15:42:30.511: E/AndroidRuntime(3785):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1177)
05-25 15:42:30.511: E/AndroidRuntime(3785):     at android.os.Handler.dispatchMessage(Handler.java:99)
05-25 15:42:30.511: E/AndroidRuntime(3785):     at android.os.Looper.loop(Looper.java:137)
05-25 15:42:30.511: E/AndroidRuntime(3785):     at android.app.ActivityThread.main(ActivityThread.java:4424)
05-25 15:42:30.511: E/AndroidRuntime(3785):     at java.lang.reflect.Method.invokeNative(Native Method)
05-25 15:42:30.511: E/AndroidRuntime(3785):     at java.lang.reflect.Method.invoke(Method.java:511)
05-25 15:42:30.511: E/AndroidRuntime(3785):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
05-25 15:42:30.511: E/AndroidRuntime(3785):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
05-25 15:42:30.511: E/AndroidRuntime(3785):     at dalvik.system.NativeStart.main(Native Method)
05-25 15:42:30.511: E/AndroidRuntime(3785): Caused by: android.os.NetworkOnMainThreadException
05-25 15:42:30.511: E/AndroidRuntime(3785):     at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1099)
05-25 15:42:30.511: E/AndroidRuntime(3785):     at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl$SSLInputStream.read(OpenSSLSocketImpl.java:664)
05-25 15:42:30.511: E/AndroidRuntime(3785):     at libcore.io.Streams.readSingleByte(Streams.java:41)
05-25 15:42:30.511: E/AndroidRuntime(3785):     at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl$SSLInputStream.read(OpenSSLSocketImpl.java:655)
05-25 15:42:30.511: E/AndroidRuntime(3785):     at libcore.net.http.HttpConnection.isStale(HttpConnection.java:256)
05-25 15:42:30.511: E/AndroidRuntime(3785):     at libcore.net.http.HttpConnectionPool.get(HttpConnectionPool.java:71)
05-25 15:42:30.511: E/AndroidRuntime(3785):     at libcore.net.http.HttpConnection.connect(HttpConnection.java:128)
05-25 15:42:30.511: E/AndroidRuntime(3785):     at libcore.net.http.HttpEngine.openSocketConnection(HttpEngine.java:308)
05-25 15:42:30.511: E/AndroidRuntime(3785):     at libcore.net.http.HttpsURLConnectionImpl$HttpsEngine.makeSslConnection(HttpsURLConnectionImpl.java:460)
05-25 15:42:30.511: E/AndroidRuntime(3785):     at libcore.net.http.HttpsURLConnectionImpl$HttpsEngine.connect(HttpsURLConnectionImpl.java:432)
05-25 15:42:30.511: E/AndroidRuntime(3785):     at libcore.net.http.HttpEngine.sendSocketRequest(HttpEngine.java:282)
05-25 15:42:30.511: E/AndroidRuntime(3785):     at libcore.net.http.HttpEngine.sendRequest(HttpEngine.java:232)
05-25 15:42:30.511: E/AndroidRuntime(3785):     at libcore.net.http.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:273)
05-25 15:42:30.511: E/AndroidRuntime(3785):     at libcore.net.http.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.java:168)
05-25 15:42:30.511: E/AndroidRuntime(3785):     at libcore.net.http.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:270)
05-25 15:42:30.511: E/AndroidRuntime(3785):     at com.facebook.android.Util.openUrl(Util.java:206)
05-25 15:42:30.511: E/AndroidRuntime(3785):     at com.facebook.android.Facebook.request(Facebook.java:751)
05-25 15:42:30.511: E/AndroidRuntime(3785):     at com.facebook.android.Facebook.request(Facebook.java:688)
05-25 15:42:30.511: E/AndroidRuntime(3785):     at org.apache.cordova.facebook.ConnectPlugin$AuthorizeListener.onComplete(ConnectPlugin.java:271)
05-25 15:42:30.511: E/AndroidRuntime(3785):     at com.facebook.android.Facebook.authorizeCallback(Facebook.java:433)
05-25 15:42:30.511: E/AndroidRuntime(3785):     at org.apache.cordova.facebook.ConnectPlugin.onActivityResult(ConnectPlugin.java:196)
05-25 15:42:30.511: E/AndroidRuntime(3785):     at org.apache.cordova.DroidGap.onActivityResult(DroidGap.java:1178)
05-25 15:42:30.511: E/AndroidRuntime(3785):     at android.app.Activity.dispatchActivityResult(Activity.java:4649)
05-25 15:42:30.511: E/AndroidRuntime(3785):     at android.app.ActivityThread.deliverResults(ActivityThread.java:2976)
05-25 15:42:30.511: E/AndroidRuntime(3785):     ... 11 more
1个回答

20
我通过将ConnectPlugin.java中的身份验证部分放入单独的线程来解决了错误。为了便于读者日后查看,我将在下面发布说明。
ConnectPlugin.java中,替换:
try {
    JSONObject o = new JSONObject(this.fba.facebook.request("/me"));
    this.fba.userId = o.getString("id");
    this.fba.success(getResponse(), this.fba.callbackId);
} catch (MalformedURLException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
} catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
} catch (JSONException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
}

使用以下代码:
Thread t = new Thread(new Runnable() {
    public void run() {
        try {
            JSONObject o = new JSONObject(fba.facebook.request("/me"));
            fba.userId = o.getString("id");
            fba.success(getResponse(), fba.callbackId);
        } catch (MalformedURLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (JSONException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
});
t.start();

那应该解决 NetworkOnMainThreadException 问题了。


谢谢!官方插件仍然存在问题。你已经提交了一个 pull request 吗? - vish
还没有。我认为自己经验不足,无法帮助解决这些问题,但今天下午我会看一下。不过我在错误部分读到了一些相关内容。 - Rex
来自未来的问候!- FYI:问题在这里的Github上 - A T

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接