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

非 Y 不嫁゛ 提交于 2019-12-12 04:44:29

问题


I'm using Facebook GraphAPI and I'm trying to load results from next page using GraphRequest.executeAndWait() as demonstrated here, but the app is crashing giving android.os.NetworkOnMainThreadException.

Here's my code:

    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);
            }
        }

Here's the stacktrace:

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$1.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$1$1.onCompleted(MainActivity.java:398)
                                                                       at com.facebook.GraphRequest$5.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)               

I'm unable to figure out what's causing this error as such errors are usually caused when this sort of code is not handled in AsyncTask but that is not the case here.

Please let me know what's causing this error and how to get rid of it.


回答1:


public void onCompleted() is run on the UI thread regardless of which thread called this request. So if you want to perform another request inside public void onCompleted(), you will have to wrap it into another AsyncTask, or other async mechanism.




回答2:


This is not the right approach

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();

You are doing that by creating a new thread. All network operations should be done in the background thread which already exists, not by creating a new thread.

The way to do this is using a handler object to run the code on main thread.

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();
            }
        }
    });

Or you can do the operation after some delay, by using 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);



回答3:


After a few google searches I got the solution.

I just wrapped the GraphRequest.executeAndWait() code in a Thread like this:

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();


来源:https://stackoverflow.com/questions/45875090/getting-android-os-networkonmainthreadexception-while-performing-graphrequest

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!