仅在 Android 4 上实现可组合创建 NPE



我在Crashlytics上遇到了很多NPE崩溃,这些崩溃与我为FirebaseRemoteConfig创建的rx包装器有关。

我的代码:

public Completable fetch() {
remoteConfig.activateFetched();
return Completable.create(e ->
remoteConfig.fetch(cacheExpiration).addOnCompleteListener(
task -> {
if (task.isSuccessful()) {
Log.d(TAG, "Config fetched successfully");
remoteConfig.activateFetched();
if (!e.isDisposed()) {
e.onComplete();
}
} else {
if (!e.isDisposed()) {
Log.e(TAG, "Config fetch error", task.getException());
e.onError(task.getException());
}
}
}));
}

然后我像这样订阅它:

composite.clear();
composite.add(
helper.fetch()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribeWith(new DisposableCompletableObserver() {
@Override
public void onComplete() {
Timber.tag(TAG).d("Remote config fetched");
}
@Override
public void onError(@NonNull Throwable throwable) {
Timber.tag(TAG).d(throwable, "Remote config fetch error");
}
})
);

我遇到 3 种类型的崩溃:

Crash #1
Fatal Exception: java.lang.NullPointerException
at io.reactivex.internal.operators.completable.CompletableCreate.subscribeActual(CompletableCreate.java:36)
at io.reactivex.Completable.subscribe(Completable.java:1635)
at io.reactivex.internal.operators.completable.CompletableSubscribeOn$SubscribeOnObserver.run(CompletableSubscribeOn.java:64)
at io.reactivex.Scheduler$DisposeTask.run(Scheduler.java:452)
at io.reactivex.internal.schedulers.ScheduledRunnable.run(ScheduledRunnable.java:61)
at io.reactivex.internal.schedulers.ScheduledRunnable.call(ScheduledRunnable.java:52)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:152)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:265)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
at java.lang.Thread.run(Thread.java:841)

Crash #2
Fatal Exception: java.lang.NullPointerException
at io.reactivex.internal.operators.completable.CompletableSubscribeOn.subscribeActual(CompletableSubscribeOn.java:36)
at io.reactivex.Completable.subscribe(Completable.java:1635)
at io.reactivex.internal.operators.completable.CompletableObserveOn.subscribeActual(CompletableObserveOn.java:34)
at io.reactivex.Completable.subscribe(Completable.java:
Crash #3
Fatal Exception: java.lang.NullPointerException
at io.reactivex.internal.operators.completable.CompletableObserveOn$ObserveOnCompletableObserver.onSubscribe(CompletableObserveOn.java:68)
at io.reactivex.internal.operators.completable.CompletableSubscribeOn.subscribeActual(CompletableSubscribeOn.java:36)
at io.reactivex.Completable.subscribe(Completable.java:1635)
at io.reactivex.internal.operators.completable.CompletableObserveOn.subscribeActual(CompletableObserveOn.java:34)
at io.reactivex.Completable.subscribe(Completable.java:1635)

奇怪的是,崩溃只发生在Android 4上,主要是4.4和4.1。

所有这些错误的共同点是,它们似乎是由预期CompletableObservernull引起的。

鉴于subscribeWith获得一个有效的对象,发生这种情况的唯一方法是通过RxJavaPlugin.onSubscribe钩子的错误配置,它可以包装观察者,因此由于某种原因将观察器替换为null

我建议使用反射检查RxJavaPlugins类中的onCompletableSubscribe字段,以查看是否有一些回调可能在这些 java 版本上表现得很奇怪。

最新更新