Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
Sum41forever opened this issue Jan 7, 2018 · 7 comments
Closed

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

Sum41forever opened this issue Jan 7, 2018 · 7 comments

Comments

@Sum41forever
Copy link
Contributor

Sum41forever commented Jan 7, 2018

这个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");
                }
            }
        };
@JessYanCoding
Copy link
Owner

@NerdAnonymous
Copy link

@JessYanCoding 我用框架之前没怎么注意这篇文章 直接上手 今天偶然发现onStop后不走回调了,我猜就是这个东西的问题,上来一找果然,稳的很

@PiPiCaptain
Copy link

@NerdAnonymous 我也遇到这问题,但看不太懂,请问要怎么处理?

@PiPiCaptain
Copy link

@NerdAnonymous 我解决了。看了一下RxLifecycle和MVPArms源码,找到了方法。
RxLifecycleUtils.bindUntilEvent(mRootView, FragmentEvent.DESTROY) 或者
RxLifecycleUtils.bindUntilEvent(mRootView, ActivityEvent.DESTROY)

@cjcj125125
Copy link

fragment里面怎么使用呢

@JessYanCoding
Copy link
Owner

@cjcj125125 和 Activity 的用法没有任何区别

@LeeeeeYao
Copy link

mModel.getTimUserAndSig(replaceToken, userRole)
.compose(RxLifecycleUtils.bindUntilEvent(mRootView, ActivityEvent.DESTROY))
.subscribe(new ErrorHandleSubscriber<BaseResponse>(mErrorHandler) {
@OverRide
public void onNext(BaseResponse userBaseResponse) {
if (userBaseResponse.isSuccess()) {
mRootView.getTimUserAndSigSuccess(userBaseResponse.getBody());
} else {
mRootView.showMessage(userBaseResponse.getMsg());
}
}
});
我添加了这样的方法,但是依然不执行onNext是什么原因呢,求助

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants