Skip to content

框架中 RxLifecycle 的绑定使用和注意事项。 #177

@Sum41forever

Description

@Sum41forever

这个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...);

这种通过继承的方法,有以下几个问题。

  1. 多一层继承关系:
    我们的基类ActivityFragment必须继承于RxActivityRxFragment,才能调用compose(bindToLifecycle()) 绑定
  2. 不适合扩展 :
    如果在MVP结构 P层中有Rx流操作,那么就不能调用 compose(bindToLifecycle()) 绑定,因为该方法在RxActivity中。同理其他类一样。
  3. 不好区分是Activity还是Fragment绑定 :
    RxLifecycle 的绑定是区分 FragmentActivity的,如果你是在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) {
                 .....//省略
                });

好处是解决了上面说的三个不足的地方。

  1. 接口实现,所以少一层继承关系
  2. 因为是工具类RxLifecycle绑定,只需要你传入一个 IView的接口就行,这意味着你可以在P或者其他地方直接使用。
  3. 工具类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");
        }
    }

注意事项

  1. Activity必须继承BaseActivity:这个很好理解,因为对RxLifecycle的实际实现核心对象是在BaseActivity
    private final BehaviorSubject<ActivityEvent> mLifecycleSubject = BehaviorSubject.create();
    public final Subject<ActivityEvent> provideLifecycleSubject() {
        return mLifecycleSubject;
    }
  1. 对于第三方的Activity是无法绑定的
    因为你不能继承BaseActivity,也可以说无法实现Lifecycleable这个接口,

  2. 如果确实不能继承BaseActivity,该如何实现RxLifecycle
    模仿BaseActivity 去实现Lifecycleable这个接口

  3. 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

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions