前几天使用retrofit + okHttp 时出现一个问题,大致情况是使用okHttp上传视频文件时app闪退,错误如下:
FATAL EXCEPTION: OkHttp Dispatcher
Process: com.******.******.******, PID: 26206
java.lang.OutOfMemoryError: Failed to allocate a 144207294 byte allocation with 16765168 free bytes and 109MB until OOM
at java.lang.StringFactory.newStringFromBytes(StringFactory.java:79)
at java.lang.StringFactory.newStringFromBytes(StringFactory.java:207)
at okio.Buffer.readString(Buffer.java:616)
at okio.Buffer.readString(Buffer.java:599)
at okhttp3.logging.HttpLoggingInterceptor.intercept(HttpLoggingInterceptor.java:199)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:67)
at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java:170)
at okhttp3.RealCall.access$100(RealCall.java:33)
at okhttp3.RealCall$AsyncCall.execute(RealCall.java:120)
at okhttp3.internal.NamedRunnable.run(NamedRunnable.java:32)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
开始因为下面还有 OutOfMemoryError 的错,怀疑是视频有问题检查,视频文件正常大小有110M,虽然大点但不应该有问题,后来定位到自定义的okHttpClient配置的log拦截器处报错:
//新建log拦截器
HttpLoggingInterceptor loggingInterceptor=new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() {
@Override
public void log(String message) {
try {
L.w("屏幕修复api"," "+message); //报错处
} catch (Exception e) {
e.printStackTrace();
L.w("屏幕修复api Exception",e.toString());
}
}
});
try{}catch()是调试的时候加的,即使加上try{}catch()仍然报错,所以说HttpLoggingInterceptor内部的错,于是各种查资料,类似情况还真有比较普遍原因是:
String data=response.body().string();
//.string()方法使用次数超过了一次。没错,你只能使用一次,至于原因看下面的源码分析。
//所以讲Log.d(“xx”,response.body().string());果断的注释掉吧。
感觉上面的错误只是方法调用有问题,不是真正的原因,继续查找,最后在Github okHttp的源码issues中找到这个cancel a async call will cause FATAL EXCEPTION #1049,源码作者之一在issues下说:We are seeing this issue too when we call cancel operation.当 call cancel operation 时会发生这个错误,至此问题算是清楚了。
总结:我的代码引起这个错的原因不值一提,是在上传文件时同时传有其他参数,那个参数不符合服务器要求,所以服务器不接收request(文件、参数1、参数2...),那么app这边就会 call cancel operation 引起了app闪退,算是okhttp的一个bug,作者最后也说了:I was hoping if we could either catch that exception properly, or find a way to neglect that issue ?所以这个bug不会被catch到,我们更拿不到这个错误,也就无法处理,app就直接闪退了。
This post has been upvoted for free by @millibot with 5%!
Get better upvotes by bidding on me.
More profits? 100% Payout! Delegate some SteemPower to @millibot: 1 SP, 5 SP, 10 SP, custom amount
You like to bet and win 20x your bid? Have a look at @gtw and this description!
Downvoting a post can decrease pending rewards and make it less visible. Common reasons:
Submit