崩溃日志如下:
08-15 13:46:34.277 2007-2007/com.ppdai.huanapp W/System.err: io.reactivex.exceptions.OnErrorNotImplementedException: The supplied value is null
08-15 13:46:34.277 2007-2007/com.ppdai.huanapp W/System.err: at io.reactivex.internal.functions.Functions$OnErrorMissingConsumer.accept(Functions.java:704)
08-15 13:46:34.277 2007-2007/com.ppdai.huanapp W/System.err: at io.reactivex.internal.functions.Functions$OnErrorMissingConsumer.accept(Functions.java:701)
08-15 13:46:34.277 2007-2007/com.ppdai.huanapp W/System.err: at io.reactivex.internal.observers.LambdaObserver.onError(LambdaObserver.java:74)
08-15 13:46:34.277 2007-2007/com.ppdai.huanapp W/System.err: at io.reactivex.observers.SerializedObserver.onError(SerializedObserver.java:155)
08-15 13:46:34.277 2007-2007/com.ppdai.huanapp W/System.err: at io.reactivex.internal.operators.observable.ObservableTakeUntil$TakeUntilObserver.onError(ObservableTakeUntil.java:73)
08-15 13:46:34.277 2007-2007/com.ppdai.huanapp W/System.err: at io.reactivex.internal.operators.observable.ObservableObserveOn$ObserveOnObserver.checkTerminated(ObservableObserveOn.java:276)
08-15 13:46:34.277 2007-2007/com.ppdai.huanapp W/System.err: at io.reactivex.internal.operators.observable.ObservableObserveOn$ObserveOnObserver.drainNormal(ObservableObserveOn.java:172)
08-15 13:46:34.277 2007-2007/com.ppdai.huanapp W/System.err: at io.reactivex.internal.operators.observable.ObservableObserveOn$ObserveOnObserver.run(ObservableObserveOn.java:252)
08-15 13:46:34.277 2007-2007/com.ppdai.huanapp W/System.err: at io.reactivex.android.schedulers.HandlerScheduler$ScheduledRunnable.run(HandlerScheduler.java:109)
08-15 13:46:34.277 2007-2007/com.ppdai.huanapp W/System.err: at android.os.Handler.handleCallback(Handler.java:725)
08-15 13:46:34.277 2007-2007/com.ppdai.huanapp W/System.err: at android.os.Handler.dispatchMessage(Handler.java:92)
08-15 13:46:34.277 2007-2007/com.ppdai.huanapp W/System.err: at android.os.Looper.loop(Looper.java:137)
08-15 13:46:34.277 2007-2007/com.ppdai.huanapp W/System.err: at android.app.ActivityThread.main(ActivityThread.java:5069)
08-15 13:46:34.277 2007-2007/com.ppdai.huanapp W/System.err: at java.lang.reflect.Method.invokeNative(Native Method)
08-15 13:46:34.277 2007-2007/com.ppdai.huanapp W/System.err: at java.lang.reflect.Method.invoke(Method.java:511)
08-15 13:46:34.277 2007-2007/com.ppdai.huanapp W/System.err: at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
08-15 13:46:34.277 2007-2007/com.ppdai.huanapp W/System.err: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
08-15 13:46:34.277 2007-2007/com.ppdai.huanapp W/System.err: at dalvik.system.NativeStart.main(Native Method)
08-15 13:46:34.277 2007-2007/com.ppdai.huanapp W/System.err: Caused by: java.lang.NullPointerException: The supplied value is null
08-15 13:46:34.277 2007-2007/com.ppdai.huanapp W/System.err: at io.reactivex.internal.operators.observable.ObservableOnErrorReturn$OnErrorReturnObserver.onError(ObservableOnErrorReturn.java:81)
08-15 13:46:34.277 2007-2007/com.ppdai.huanapp W/System.err: at retrofit2.adapter.rxjava2.BodyObservable$BodyObserver.onError(BodyObservable.java:72)
08-15 13:46:34.277 2007-2007/com.ppdai.huanapp W/System.err: at retrofit2.adapter.rxjava2.CallExecuteObservable.subscribeActual(CallExecuteObservable.java:55)
08-15 13:46:34.277 2007-2007/com.ppdai.huanapp W/System.err: at io.reactivex.Observable.subscribe(Observable.java:10842)
08-15 13:46:34.277 2007-2007/com.ppdai.huanapp W/System.err: at retrofit2.adapter.rxjava2.BodyObservable.subscribeActual(BodyObservable.java:34)
08-15 13:46:34.277 2007-2007/com.ppdai.huanapp W/System.err: at io.reactivex.Observable.subscribe(Observable.java:10842)
08-15 13:46:34.277 2007-2007/com.ppdai.huanapp W/System.err: at io.reactivex.internal.operators.observable.ObservableOnErrorReturn.subscribeActual(ObservableOnErrorReturn.java:31)
08-15 13:46:34.277 2007-2007/com.ppdai.huanapp W/System.err: at io.reactivex.Observable.subscribe(Observable.java:10842)
08-15 13:46:34.277 2007-2007/com.ppdai.huanapp W/System.err: at io.reactivex.internal.operators.observable.ObservableSubscribeOn$SubscribeTask.run(ObservableSubscribeOn.java:96)
08-15 13:46:34.277 2007-2007/com.ppdai.huanapp W/System.err: at io.reactivex.Scheduler$DisposeTask.run(Scheduler.java:452)
08-15 13:46:34.277 2007-2007/com.ppdai.huanapp W/System.err: at io.reactivex.internal.schedulers.ScheduledRunnable.run(ScheduledRunnable.java:61)
08-15 13:46:34.277 2007-2007/com.ppdai.huanapp W/System.err: at io.reactivex.internal.schedulers.ScheduledRunnable.call(ScheduledRunnable.java:52)
08-15 13:46:34.277 2007-2007/com.ppdai.huanapp W/System.err: at java.util.concurrent.FutureTask.run(FutureTask.java:234)
08-15 13:46:34.277 2007-2007/com.ppdai.huanapp W/System.err: at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:153)
08-15 13:46:34.277 2007-2007/com.ppdai.huanapp W/System.err: at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:267)
08-15 13:46:34.277 2007-2007/com.ppdai.huanapp W/System.err: at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080)
08-15 13:46:34.277 2007-2007/com.ppdai.huanapp W/System.err: at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573)
08-15 13:46:34.277 2007-2007/com.ppdai.huanapp W/System.err: at java.lang.Thread.run(Thread.java:856)
08-15 13:46:34.277 2007-2007/com.ppdai.huanapp W/System.err: Caused by: java.lang.IllegalStateException: closed
08-15 13:46:34.277 2007-2007/com.ppdai.huanapp W/System.err: at okio.RealBufferedSource.read(RealBufferedSource.java:43)
08-15 13:46:34.277 2007-2007/com.ppdai.huanapp W/System.err: at okio.ForwardingSource.read(ForwardingSource.java:35)
08-15 13:46:34.277 2007-2007/com.ppdai.huanapp W/System.err: at retrofit2.OkHttpCall$ExceptionCatchingRequestBody$1.read(OkHttpCall.java:291)
08-15 13:46:34.277 2007-2007/com.ppdai.huanapp W/System.err: at okio.RealBufferedSource.request(RealBufferedSource.java:67)
08-15 13:46:34.277 2007-2007/com.ppdai.huanapp W/System.err: at okio.RealBufferedSource.rangeEquals(RealBufferedSource.java:408)
08-15 13:46:34.277 2007-2007/com.ppdai.huanapp W/System.err: at okio.RealBufferedSource.rangeEquals(RealBufferedSource.java:392)
08-15 13:46:34.277 2007-2007/com.ppdai.huanapp W/System.err: at okhttp3.internal.Util.bomAwareCharset(Util.java:431)
08-15 13:46:34.277 2007-2007/com.ppdai.huanapp W/System.err: at okhttp3.ResponseBody$BomAwareReader.read(ResponseBody.java:249)
08-15 13:46:34.277 2007-2007/com.ppdai.huanapp W/System.err: at com.google.gson.stream.JsonReader.fillBuffer(JsonReader.java:1287)
08-15 13:46:34.277 2007-2007/com.ppdai.huanapp W/System.err: at com.google.gson.stream.JsonReader.nextNonWhitespace(JsonReader.java:1325)
08-15 13:46:34.277 2007-2007/com.ppdai.huanapp W/System.err: at com.google.gson.stream.JsonReader.doPeek(JsonReader.java:549)
08-15 13:46:34.277 2007-2007/com.ppdai.huanapp W/System.err: at com.google.gson.stream.JsonReader.peek(JsonReader.java:425)
08-15 13:46:34.277 2007-2007/com.ppdai.huanapp W/System.err: at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:205)
08-15 13:46:34.277 2007-2007/com.ppdai.huanapp W/System.err: at retrofit2.converter.gson.GsonResponseBodyConverter.convert(GsonResponseBodyConverter.java:37)
08-15 13:46:34.277 2007-2007/com.ppdai.huanapp W/System.err: at retrofit2.converter.gson.GsonResponseBodyConverter.convert(GsonResponseBodyConverter.java:25)
08-15 13:46:34.277 2007-2007/com.ppdai.huanapp W/System.err: at retrofit2.ServiceMethod.toResponse(ServiceMethod.java:119)
08-15 13:46:34.277 2007-2007/com.ppdai.huanapp W/System.err: at retrofit2.OkHttpCall.parseResponse(OkHttpCall.java:218)
08-15 13:46:34.277 2007-2007/com.ppdai.huanapp W/System.err: at retrofit2.OkHttpCall.execute(OkHttpCall.java:180)
08-15 13:46:34.277 2007-2007/com.ppdai.huanapp W/System.err: at retrofit2.adapter.rxjava2.CallExecuteObservable.subscribeActual(CallExecuteObservable.java:41)
08-15 13:46:34.277 2007-2007/com.ppdai.huanapp W/System.err: ... 15 more
仔细查看以上日志,发现发生空指针异常的地方并不是在自己代码中,这也加大了修复难度,只能逐步查看调用堆栈,找出具体问题点,接下来和我一起来分析这个问题吧, Let's go!!
步骤一:Caused by: java.lang.NullPointerException: The supplied value is null
根据Caused by: java.lang.NullPointerException: The supplied value is null,打开ObservableOnErrorReturn.java文件,代码如下:
public void onError(Throwable t) {
T v;
try {
v = valueSupplier.apply(t);
} catch (Throwable e) {
Exceptions.throwIfFatal(e);
actual.onError(new CompositeException(t, e));
return;
}
if (v == null) {
NullPointerException e = new NullPointerException("The supplied value is null");
e.initCause(t);
actual.onError(e);
return;
}
actual.onNext(v);
actual.onComplete();
}
到这里我们知道这个空指针异常时手动抛出来的,同时发现这个异常是因为v == null, 也就是网络请求结果为空。我们再往下看
步骤二: Caused by: java.lang.IllegalStateException: closed
根据 Caused by: java.lang.IllegalStateException: closed,打开(RealBufferedSource.java:43)文件,代码如下:
@Override public long read(Buffer sink, long byteCount) throws IOException {
if (sink == null) throw new IllegalArgumentException("sink == null");
if (byteCount < 0) throw new IllegalArgumentException("byteCount < 0: " + byteCount);
if (closed) throw new IllegalStateException("closed");
if (buffer.size == 0) {
long read = source.read(buffer, Segment.SIZE);
if (read == -1) return -1;
}
long toRead = Math.min(byteCount, buffer.size);
return buffer.read(sink, toRead);
}
同样这个一场也是手动抛出来,抛异常的条件是closed为真,接下来我们查看该bool值在哪可以修改,通过搜索该值,发现以下方法:
@Override public void close() throws IOException {
if (closed) return;
closed = true;
source.close();
buffer.clear();
}
至此我们明白了[The supplied value is null]的最终原因,原因找到了,接下来我们再来找解决方案
步骤三:close方法断点,查看调用堆栈。
调用堆栈如下:
终于看到了自己的代码(开心中......),打开对应的文件,代码如下:
.addInterceptor(new Interceptor() {
@Override
public Response intercept(Chain chain) throws IOException {
Response response = chain.proceed(chain.request());
MediaType mediaType = response.body().contentType();
LogUtils.e(chain.request().url().toString());
LogUtils.e(chain.request().body());
String content = response.body().string();
LogUtils.e(content);
return response;
}
})
这个拦截器是为了打印网络请求日志,调用了response.body().string()方法,而string()方法有调用了Util.closeQuietly(source)方法,代码如下:
public final String string() throws IOException {
BufferedSource source = source();
try {
Charset charset = Util.bomAwareCharset(source, charset());
return source.readString(charset);
} finally {
Util.closeQuietly(source);
}
}
步骤四:解决问题
方案1:直接删除 response.body().string()的调用,这里你可能会说,我就想打印入职,要怎么办?
方案2:调用万 response.body().string()方法,我们创建一个新的 response返回,代码如下:
.addInterceptor(new Interceptor() {
@Override
public Response intercept(Chain chain) throws IOException {
.......
MediaType mediaType = response.body().contentType();
......
String content = response.body().string();
LogUtils.e(content);
return response.newBuilder()
.body(ResponseBody.create(mediaType, content))
.build();
}
})
总结:
遇到问题不能急,要根据已有的信息,逐步找到问题所在,找到了问题所在,就离解决问题不远了!!!
更多内容可以关注我的公众号或者搜索SamuelAndroid关注我: