-
Notifications
You must be signed in to change notification settings - Fork 2.4k
Closed
Description
这个Issue不涉及 RxLifecycle 原理,原理可以参考我写的一篇Blog Android Rxlifecycle 实现原理及过程,如果发现问题,欢迎交流,共同进步 。
常规 RxLifecycle 的使用和缺点
RxLifecycle 的常规使用是通过继承RxActivity,然后在子类Activity中如下面的这样使用
RetrofitHelper.getApi().login()//登陆接口
.compose(this.<BaseModel<List<BasicData>>>bindToLifecycle())//绑定生命周期
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Acition...);这种通过继承的方法,有以下几个问题。
- 多一层继承关系:
我们的基类Activity,Fragment必须继承于RxActivity,RxFragment,才能调用compose(bindToLifecycle()) 绑定 - 不适合扩展 :
如果在MVP结构 P层中有Rx流操作,那么就不能调用 compose(bindToLifecycle()) 绑定,因为该方法在RxActivity中。同理其他类一样。 - 不好区分是Activity还是Fragment绑定 :
RxLifecycle 的绑定是区分 Fragment 和 Activity的,如果你是在P里面把View接口强转成RxActivity,那么就可能出错。因为如果P可以在Fragment复用,那么强转就会带来问题。而且View接口的父类可能是RxActivity,也有可能是RxFragmentActivity,当然你可以通过if else + insteadof 来处理,但是每个流都这么写是很痛苦的,代码不好读,也很繁琐。
框架中RxLifecycle 绑定
框架对RxLifecycle的实现方式 是通过接口Lifecycleable实现 具体实现在父类BaseActivity中
绑定方式是通过工具类 RxLifecycleUtils
mModel.getUsers(lastUserId, isEvictCache)
.subscribeOn(Schedulers.io())
.compose(RxLifecycleUtils.bindToLifecycle(mRootView))//使用 Rxlifecycle,使 Disposable 和 Activity 一起销毁
.subscribe(new ErrorHandleSubscriber<List<User>>(mErrorHandler) {
.....//省略
});好处是解决了上面说的三个不足的地方。
- 接口实现,所以少一层继承关系
- 因为是工具类RxLifecycle绑定,只需要你传入一个 IView的接口就行,这意味着你可以在P或者其他地方直接使用。
- 工具类RxLifecycle绑定过程中会自动判断是Activity类型绑定还是Fragment类型绑定
//绑定 Activity/Fragment 的生命周期
public static <T> LifecycleTransformer<T> bindToLifecycle(@NonNull IView view) {
if (view instanceof Lifecycleable) {
return bindToLifecycle((Lifecycleable) view);
} else {
throw new IllegalArgumentException("view isn't Lifecycleable");
}
}
public static <T> LifecycleTransformer<T> bindToLifecycle(@NonNull Lifecycleable lifecycleable) {
if (lifecycleable instanceof ActivityLifecycleable) {
return RxLifecycleAndroid.bindActivity(((ActivityLifecycleable) lifecycleable).provideLifecycleSubject());
} else if (lifecycleable instanceof FragmentLifecycleable) {
return RxLifecycleAndroid.bindFragment(((FragmentLifecycleable) lifecycleable).provideLifecycleSubject());
} else {
throw new IllegalArgumentException("Lifecycleable not match");
}
}注意事项
- Activity必须继承BaseActivity:这个很好理解,因为对RxLifecycle的实际实现核心对象是在BaseActivity中
private final BehaviorSubject<ActivityEvent> mLifecycleSubject = BehaviorSubject.create();
public final Subject<ActivityEvent> provideLifecycleSubject() {
return mLifecycleSubject;
}-
对于第三方的Activity是无法绑定的
因为你不能继承BaseActivity,也可以说无法实现Lifecycleable这个接口, -
如果确实不能继承BaseActivity,该如何实现RxLifecycle
模仿BaseActivity 去实现Lifecycleable这个接口 -
RxLifecycle 绑定后自动取消订阅的时间(下面的方法来自RxLifecycle源码)
// 这个方法的含义是判断绑定的时间:如果是在Create中绑定的,那么就返回DESTROY,就是说会在onDestroy方法取消整个流的订阅
private static final Func1<ActivityEvent, ActivityEvent> ACTIVITY_LIFECYCLE =
new Func1<ActivityEvent, ActivityEvent>() {
@Override
public ActivityEvent call(ActivityEvent lastEvent) {
switch (lastEvent) {
case CREATE:// CREATE绑定 -> DESTROY取消整个流的订阅
return ActivityEvent.DESTROY;
case START: // START绑定 -> STOP取消整个流的订阅
return ActivityEvent.STOP;
case RESUME: // RESUME绑定 -> PAUSE取消整个流的订阅
return ActivityEvent.PAUSE;
case PAUSE: // PAUSE绑定 -> STOP取消整个流的订阅
return ActivityEvent.STOP;
case STOP: // STOP绑定 -> DESTROY取消整个流的订阅
return ActivityEvent.DESTROY;
case DESTROY: // DESTROY -> 抛出异常(后面会处理这个异常,也会取消整个流的订阅)
throw new OutsideLifecycleException("Cannot bind to Activity lifecycle when outside of it.");
default:
throw new UnsupportedOperationException("Binding to " + lastEvent + " not yet implemented");
}
}
};
// 对Fragment的
private static final Function<FragmentEvent, FragmentEvent> FRAGMENT_LIFECYCLE =
new Function<FragmentEvent, FragmentEvent>() {
@Override
public FragmentEvent apply(FragmentEvent lastEvent) throws Exception {
switch (lastEvent) {
case ATTACH:
return FragmentEvent.DETACH;
case CREATE:
return FragmentEvent.DESTROY;
case CREATE_VIEW:
return FragmentEvent.DESTROY_VIEW;
case START:
return FragmentEvent.STOP;
case RESUME:
return FragmentEvent.PAUSE;
case PAUSE:
return FragmentEvent.STOP;
case STOP:
return FragmentEvent.DESTROY_VIEW;
case DESTROY_VIEW:
return FragmentEvent.DESTROY;
case DESTROY:
return FragmentEvent.DETACH;
case DETACH:
throw new OutsideLifecycleException("Cannot bind to Fragment lifecycle when outside of it.");
default:
throw new UnsupportedOperationException("Binding to " + lastEvent + " not yet implemented");
}
}
};Metadata
Metadata
Assignees
Labels
No labels