在 AsyncTask 的 doInBackground() 中执行 GraphRequest.executeAndWait() 时获取 'android.os.NetworkOnMainThreadException'

Getting 'android.os.NetworkOnMainThreadException' while performing GraphRequest.executeAndWait() in doInBackground() of AsyncTask

我正在使用 Facebook GraphAPI,我正在尝试使用 GraphRequest.executeAndWait() 从下一页加载结果,如 所示,但应用程序崩溃并给出 android.os.NetworkOnMainThreadException

这是我的代码:

    class RetrieveF extends AsyncTask<Void, Integer, String> {

            GraphRequest request;

            protected String doInBackground(Void...args0) {
                new GraphRequest(
                        AccessToken.getCurrentAccessToken(), "/me/friends", null, HttpMethod.GET,
                        new GraphRequest.Callback() {
                            public void onCompleted(GraphResponse response) {
                                JSONObject innerJson = response.getJSONObject();
                                try {
                                    JSONArray data = innerJson.getJSONArray("data");
                                    for (int i = 0; i<data.length(); i++){

                                        String id = data.getJSONObject(i).getString("id");

                                        request = new GraphRequest(AccessToken.getCurrentAccessToken(), id+"/feed", null, HttpMethod.GET,
                                                new GraphRequest.Callback() {
                                                    @Override
                                                    public void onCompleted(GraphResponse response) {

                                                        JSONObject innerJson = response.getJSONObject();
                                                        try {
                                                            JSONArray data = innerJson.getJSONArray("data");
                                                            for (int i = 0; i<data.length(); i++) {
                                                                JSONObject obj = data.getJSONObject(i);}
                                                        } catch (JSONException e) {
                                                            Log.d("innerFacebookException", e.getMessage());
                                                        }

                                                        GraphRequest nextResultsRequests = response.getRequestForPagedResults(GraphResponse.PagingDirection.NEXT);
                                                        if (nextResultsRequests != null) {
                                                            nextResultsRequests.setCallback(request.getCallback());
                                                            // error on this line
                                                            response = nextResultsRequests.executeAndWait();
                                                            //
                                                        }
                                                    }
                                                }
                                        );
                                        request.executeAsync();
                                    }
                                } catch (JSONException e) {
                                    Log.d("facebookException", e.getMessage());
                                }
                            }
                        }
                ).executeAsync();
                return "success";
            }

            @Override
            protected void onPostExecute(String s) {
                super.onPostExecute(s);
            }
        }

这是堆栈跟踪:

android.os.NetworkOnMainThreadException
                                                                       at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1273)
                                                                       at com.android.org.conscrypt.OpenSSLSocketImpl.shutdownAndFreeSslNative(OpenSSLSocketImpl.java:1131)
                                                                       at com.android.org.conscrypt.OpenSSLSocketImpl.close(OpenSSLSocketImpl.java:1126)
                                                                       at com.android.okhttp.Connection.closeIfOwnedBy(Connection.java:132)
                                                                       at com.android.okhttp.OkHttpClient.closeIfOwnedBy(OkHttpClient.java:75)
                                                                       at com.android.okhttp.internal.http.HttpConnection.closeIfOwnedBy(HttpConnection.java:137)
                                                                       at com.android.okhttp.internal.http.HttpTransport.disconnect(HttpTransport.java:135)
                                                                       at com.android.okhttp.internal.http.HttpEngine.disconnect(HttpEngine.java:578)
                                                                       at com.android.okhttp.internal.huc.HttpURLConnectionImpl.disconnect(HttpURLConnectionImpl.java:122)
                                                                       at com.android.okhttp.internal.huc.DelegatingHttpsURLConnection.disconnect(DelegatingHttpsURLConnection.java:93)
                                                                       at com.android.okhttp.internal.huc.HttpsURLConnectionImpl.disconnect(HttpsURLConnectionImpl.java)
                                                                       at com.facebook.internal.Utility.disconnectQuietly(Utility.java:416)
                                                                       at com.facebook.GraphRequest.executeConnectionAndWait(GraphRequest.java:1272)
                                                                       at com.facebook.GraphRequest.executeBatchAndWait(GraphRequest.java:1168)
                                                                       at com.facebook.GraphRequest.executeBatchAndWait(GraphRequest.java:1134)
                                                                       at com.facebook.GraphRequest.executeBatchAndWait(GraphRequest.java:1118)
                                                                       at com.facebook.GraphRequest.executeAndWait(GraphRequest.java:1093)
                                                                       at com.facebook.GraphRequest.executeAndWait(GraphRequest.java:987)
                                                                       at com.qbc.xxx.MainActivity$RetrieveFacebookPosts.onCompleted(MainActivity.java:398)
                                                                       at com.facebook.GraphRequest.run(GraphRequest.java:1383)
                                                                       at android.os.Handler.handleCallback(Handler.java:739)
                                                                       at android.os.Handler.dispatchMessage(Handler.java:95)
                                                                       at android.os.Looper.loop(Looper.java:148)
                                                                       at android.app.ActivityThread.main(ActivityThread.java:5417)
                                                                       at java.lang.reflect.Method.invoke(Native Method)
                                                                       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
                                                                       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)               

我无法找出导致此错误的原因,因为此类错误通常是在 AsyncTask 中未处理此类代码时引起的,但此处并非如此。

请告诉我导致此错误的原因以及如何消除它。

public void onCompleted() 在 UI 线程上是 运行,无论哪个线程调用了这个请求。因此,如果您想在 public void onCompleted() 中执行另一个请求,则必须将其包装到另一个 AsyncTask 或其他异步机制中。

经过几次 google 搜索后,我得到了解决方案。

我只是将 GraphRequest.executeAndWait() 代码包装在 Thread 中,如下所示:

Thread t = new Thread() {
    @Override
    public void run() {
        GraphRequest nextResultsRequests = lastGraphResponse.getRequestForPagedResults(GraphResponse.PagingDirection.NEXT);
        if (nextResultsRequests != null) {
            nextResultsRequests.setCallback(request.getCallback());
            lastGraphResponse = nextResultsRequests.executeAndWait();
        }
    }
};
t.start();

这不是正确的方法

Thread t = new Thread() {
@Override
public void run() {
    GraphRequest nextResultsRequests = lastGraphResponse.getRequestForPagedResults(GraphResponse.PagingDirection.NEXT);
    if (nextResultsRequests != null) {
        nextResultsRequests.setCallback(request.getCallback());
        lastGraphResponse = nextResultsRequests.executeAndWait();
    }
}

}.start();

你正在通过创建一个新线程来做到这一点。所有网络操作都应该在已经存在的后台线程中完成,而不是通过创建新线程。

执行此操作的方法是使用 处理程序 对象 运行 主线程 上的代码。

Handler handler = new Handler();
    handler.post(new Runnable() {
        @Override
        public void run() {
            GraphRequest nextResultsRequests = lastGraphResponse.getRequestForPagedResults(GraphResponse.PagingDirection.NEXT);
            if (nextResultsRequests != null) {
                nextResultsRequests.setCallback(request.getCallback());
                lastGraphResponse = nextResultsRequests.executeAndWait();
            }
        }
    });

或者您可以在延迟一段时间后执行操作,方法是使用 postDelayed

handler.postDelayed(new Runnable() {
        @Override
        public void run() {
            GraphRequest nextResultsRequests = lastGraphResponse.getRequestForPagedResults(GraphResponse.PagingDirection.NEXT);
            if (nextResultsRequests != null) {
                nextResultsRequests.setCallback(request.getCallback());
                lastGraphResponse = nextResultsRequests.executeAndWait();
            }
        }
    }, DELAY_IN MILLISECONDS);