报错如下:
Lifecycles can only be bound to on the main thread!
使用场景:客户端本来使用封装好的Rxjava,用的好好的。但是现在客户端实现了一个弹框,该弹框涉及到接口请求,使用的还是封装好的网络请求。然后h5页面调起该弹框,这时候在弹框中发起请求的时候就报错了!如上所示!
封装的请求:
@JvmStatic
fun <T> toSubscribe(context: Context?, observable: Observable<T>?, observer: Observer<T>?) {
if (context != null && observable != null && observer != null) {
if (context is AppCompatActivity) {
observable.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
//使用AutoDispose优雅的实现RxJava自动解绑
.autoDisposable(AndroidLifecycleScopeProvider.from(context,Lifecycle.Event.ON_DESTROY))//OnDestory时自动解绑
.subscribe(observer)
} else {
observable.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(observer)
}
}
}
AutoDispose库我们看LifecycleEventsObservable类
class LifecycleEventsObservable extends Observable<Event> {
//省略部分代码
@Override protected void subscribeActual(Observer<? super Event> observer) {
ArchLifecycleObserver archObserver = new ArchLifecycleObserver(lifecycle, observer, eventsObservable);
observer.onSubscribe(archObserver);
if (!isMainThread()) { //非主线程,直接抛出异常
observer.onError(new IllegalStateException("Lifecycles can only be bound to on the main thread!"));
return;
}
lifecycle.addObserver(archObserver); //添加观察者
if (archObserver.isDisposed()) {
lifecycle.removeObserver(archObserver);
}
}
//省略部分代码
可以看到,AutoDispose是在事件订阅时添加观察者,并且当前非主线程时,直接抛出异常,也就说明使用AutoDispose不能在子线程订阅事件。在移除观察者方面,AutoDispose会在事件结束或者页面销毁时移除观察者,这一点要优于RxLifecycle。
简单直接的解决办法,就是判断是否在主线程,以此决定是否使用AutoDispose。
@JvmStatic
fun <T> toSubscribe(context: Context?, observable: Observable<T>?, observer: Observer<T>?) {
if (context != null && observable != null && observer != null) {
if (context is AppCompatActivity) {
//使用AutoDispose优雅的实现RxJava自动解绑,但是只能在主线程中
if (ThreadUtils.isMainThread()) {
observable.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.autoDisposable(AndroidLifecycleScopeProvider.from(context, Lifecycle.Event.ON_DESTROY))//OnDestory时自动解绑
.subscribe(observer)
} else {
observable.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(observer)
}
} else {
observable.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(observer)
}
}
}
至此,报错问题解决。但是需要优化的地方就是这种情况下,怎么避免Rxjava可能会出现的内存泄露问题。。。