gpt4 book ai didi

android - 这个 NetworkOnMainThreadException 的原因是什么

转载 作者:太空狗 更新时间:2023-10-29 14:48:08 26 4
gpt4 key购买 nike

在您将鼠标悬停在关闭按钮上之前。请完整阅读此问题。

前言

很明显,这个异常是在Main Thread上运行网络操作引起的。但是,正如您从堆栈跟踪中看到的那样,此错误源自 doInBackground。的 AsyncTask !在那之后我也不会过渡到主线程。

有趣的是,我无法在我的设备上重现此问题。对于我的绝大多数用户来说,这也不是突然出现的问题。因此,它不能是一般的实现错误。

步骤

  1. 主线程
  2. 某些原因导致 channel 列表刷新(手动或初始加载)
  3. 我的 API 库调用(附录 1)
  4. 后台线程
  5. AsyncTask调用 API 库获取 URL 正文(附录 2)
  6. 我的缓存库检查正文是否已经保存,它不会改变Thread .
  7. API 库调用必要的 OkHttp提取 URL 正文的方法(附录 3)

堆栈跟踪

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)

附录1

public void getChannelList(final IGetChannelListCallback callback) {
try {
GetChannelListTask task = new GetChannelListTask(mContext.get(), callback);
AsyncTaskCompat.executeParallel(task);
} catch (RejectedExecutionException e) {
Crashlytics.logException(e);
}
}

附录2

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

附录3

@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 "";
}

更新1

检查线程得到了预期的结果:

refreshChannelList: MainThread: true
getChannelList: MainThread: true
onPreExecute: MainThread: true
doInBackground: MainThread: false
renewCache: MainThread: false
getBody: MainThread: false
onPostExecute: MainThread: true

doInBackground 后转到后台线程并继续到 OkHttp调用,一次返回到主线程 onPostExecute .

最佳答案

嗯,如果你在 doInbackground 方法中做某事(使用上下文调用某些操作),看起来就像你的问题。如果您的 Activity/Fragment 等上下文实例(取自 UI 组件),则意味着使用您的上下文的操作使用 MainThread 执行。这就是为什么你能得到这样的异常(exception)。尝试执行这个

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

@Override
protected void onProgressUpdate(Object... values) {
super.onProgressUpdate(values);

}

使用 publishProgress(Object obj);在 doInbackground 方法上。一定有帮助

关于android - 这个 NetworkOnMainThreadException 的原因是什么,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37702610/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com