在 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);
我正在使用 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);