将鼠标悬停在关闭按钮上之前。请完整阅读这个问题。
显然,此异常是由在主线程上运行网络操作引起的。但是,正如您从堆栈跟踪中看到的,此错误源自doInBackground
的{{1}}!在那之后我也没有转换到主线程。
有趣的是,我无法在我的设备上复制此问题。对于绝大多数用户而言,这也不是一个问题。因此,它不能是一般的实现错误。
AsyncTask
调用API库以获取URL的主体(附录2)AsyncTask
。Thread
方法来提取URL的主体(附录3)OkHttp
Fatal Exception: java.lang.RuntimeException: An error occurred while executing doInBackground()
at android.os.AsyncTask$3.done(AsyncTask.java:309)
at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:354)
at java.util.concurrent.FutureTask.setException(FutureTask.java:223)
at java.util.concurrent.FutureTask.run(FutureTask.java:242)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
at java.lang.Thread.run(Thread.java:818)
Caused by android.os.NetworkOnMainThreadException
at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1273)
at libcore.io.BlockGuardOs.recvfrom(BlockGuardOs.java:249)
at libcore.io.IoBridge.recvfrom(IoBridge.java:549)
at java.net.PlainSocketImpl.read(PlainSocketImpl.java:481)
at java.net.PlainSocketImpl.access$000(PlainSocketImpl.java:37)
at java.net.PlainSocketImpl$PlainSocketInputStream.read(PlainSocketImpl.java:237)
at okio.Okio$2.read(SourceFile:139)
at okio.AsyncTimeout$2.read(SourceFile:211)
at okio.RealBufferedSource.indexOf(SourceFile:306)
at okio.RealBufferedSource.indexOf(SourceFile:300)
at okio.RealBufferedSource.readUtf8LineStrict(SourceFile:196)
at okhttp3.internal.http.Http1xStream.readResponse(SourceFile:184)
at okhttp3.internal.http.Http1xStream.readResponseHeaders(SourceFile:125)
at okhttp3.internal.http.HttpEngine.readNetworkResponse(SourceFile:723)
at okhttp3.internal.http.HttpEngine.access$200(SourceFile:81)
at okhttp3.internal.http.HttpEngine$NetworkInterceptorChain.proceed(SourceFile:708)
at okhttp3.internal.http.HttpEngine.readResponse(SourceFile:563)
at okhttp3.RealCall.getResponse(SourceFile:241)
at okhttp3.RealCall$ApplicationInterceptorChain.proceed(SourceFile:198)
at okhttp3.RealCall.getResponseWithInterceptorChain(SourceFile:160)
at okhttp3.RealCall.execute(SourceFile:57)
at com.mypackagename.app.http.Api.getBody(SourceFile:1472)
at com.mypackagename.app.tasks.GetChannelListTask$2.renewCache(SourceFile:72)
at com.mypackagename.app.utils.Cache.get(SourceFile:27)
at com.mypackagename.app.tasks.GetChannelListTask.doInBackground(SourceFile:69)
at com.mypackagename.app.tasks.GetChannelListTask.doInBackground(SourceFile:24)
at android.os.AsyncTask$2.call(AsyncTask.java:295)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
at java.lang.Thread.run(Thread.java:818)
public void getChannelList(final IGetChannelListCallback callback) {
try {
GetChannelListTask task = new GetChannelListTask(mContext.get(), callback);
AsyncTaskCompat.executeParallel(task);
} catch (RejectedExecutionException e) {
Crashlytics.logException(e);
}
}
protected ArrayList<Channel> doInBackground(String... urls) {
final ArrayList<Channel> channelList = new ArrayList<Channel>();
// ...
String json = Cache.get(context, GET_CHANNELS_CACHE, GET_CHANNELS_CACHE_TIME, new IBadCache() {
public String renewCache() {
return Api.getInstance(context).getBody(GET_CHANNELS_URL);
}
});
// ...
return channelList;
}
检查线程导致了预期的结果:
@WorkerThread
@NonNull
public String getBody(@NonNull final String url) {
try {
Request request = new Request.Builder()
.url(logUrl(url))
.build();
Response response = mClient.newCall(request).execute();
return response.body().string();
} catch (IOException e) {
Utils.log("API", "E::"+e.toString());
} catch (SecurityException e) {
reportNoInternetPermission();
}
return "";
}
移至refreshChannelList: MainThread: true
getChannelList: MainThread: true
onPreExecute: MainThread: true
doInBackground: MainThread: false
renewCache: MainThread: false
getBody: MainThread: false
onPostExecute: MainThread: true
后台线程并继续doInBackground
来电,在OkHttp
返回主线程。
答案 0 :(得分:0)
嗯,看起来像你在doInbackground方法中做某事(用上下文用法调用一些操作)的问题。如果Activity / Fragment等的上下文实例(取自UI组件)表示使用上下文的操作使用MainThread执行。这就是为什么你会得到这样的例外。 尝试执行此
String json = Cache.get(context, GET_CHANNELS_CACHE, GET_CHANNELS_CACHE_TIME, new IBadCache() {
public String renewCache() {
return Api.getInstance(context).getBody(GET_CHANNELS_URL);
}
});
on
@Override
protected void onProgressUpdate(Object... values) {
super.onProgressUpdate(values);
}
使用publishProgress(Object obj);在doInbackground方法上。它必须帮助