{"action":"created","issue":{"url":"https://api.github.com/repos/JessYanCoding/MVPArms/issues/177","repository_url":"https://api.github.com/repos/JessYanCoding/MVPArms","labels_url":"https://api.github.com/repos/JessYanCoding/MVPArms/issues/177/labels{/name}","comments_url":"https://api.github.com/repos/JessYanCoding/MVPArms/issues/177/comments","events_url":"https://api.github.com/repos/JessYanCoding/MVPArms/issues/177/events","html_url":"https://github.com/JessYanCoding/MVPArms/issues/177","id":286558399,"node_id":"MDU6SXNzdWUyODY1NTgzOTk=","number":177,"title":"框架中 RxLifecycle 的绑定使用和注意事项。","user":{"login":"Sum41forever","id":18468976,"node_id":"MDQ6VXNlcjE4NDY4OTc2","avatar_url":"https://avatars0.githubusercontent.com/u/18468976?v=4","gravatar_id":"","url":"https://api.github.com/users/Sum41forever","html_url":"https://github.com/Sum41forever","followers_url":"https://api.github.com/users/Sum41forever/followers","following_url":"https://api.github.com/users/Sum41forever/following{/other_user}","gists_url":"https://api.github.com/users/Sum41forever/gists{/gist_id}","starred_url":"https://api.github.com/users/Sum41forever/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Sum41forever/subscriptions","organizations_url":"https://api.github.com/users/Sum41forever/orgs","repos_url":"https://api.github.com/users/Sum41forever/repos","events_url":"https://api.github.com/users/Sum41forever/events{/privacy}","received_events_url":"https://api.github.com/users/Sum41forever/received_events","type":"User","site_admin":false},"labels":[],"state":"closed","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":3,"created_at":"2018-01-07T10:09:37Z","updated_at":"2019-01-05T03:51:59Z","closed_at":"2018-01-07T10:13:45Z","author_association":"CONTRIBUTOR","body":"> 这个Issue不涉及 RxLifecycle 原理，原理可以参考我写的一篇Blog [Android Rxlifecycle 实现原理及过程](http://www.sum41forever.com/post/5c5e110400c2)，如果发现问题，欢迎交流，共同进步 。\r\n\r\n## 常规 RxLifecycle 的使用和缺点\r\n**RxLifecycle** 的常规使用是通过继承**RxActivity**，然后在子类Activity中如下面的这样使用\r\n```java\r\n    RetrofitHelper.getApi().login()//登陆接口\r\n            .compose(this.<BaseModel<List<BasicData>>>bindToLifecycle())//绑定生命周期\r\n            .subscribeOn(Schedulers.io())\r\n            .observeOn(AndroidSchedulers.mainThread())\r\n            .subscribe(new Acition...);\r\n```\r\n这种通过继承的方法，有以下几个问题。\r\n1. 多一层继承关系：\r\n我们的基类**Activity**，**Fragment**必须继承于**RxActivity**，**RxFragment**，才能调用**compose(bindToLifecycle())** 绑定\r\n2. 不适合扩展 ：\r\n如果在**MVP**结构 **P**层中有**Rx**流操作，那么就不能调用 **compose(bindToLifecycle())** 绑定，因为该方法在**RxActivity**中。同理其他类一样。\r\n3. 不好区分是**Activity**还是**Fragment**绑定 ：\r\n**RxLifecycle** 的绑定是区分 **Fragment** 和 **Activity**的，如果你是在**P**里面把**View接口**强转成**RxActivity**，那么就可能出错。因为如果**P**可以在**Fragment**复用，那么强转就会带来问题。而且**View接口**的父类可能是**RxActivity**,也有可能是**RxFragmentActivity**，当然你可以通过if else + insteadof 来处理，但是每个流都这么写是很痛苦的，代码不好读，也很繁琐。\r\n\r\n---\r\n## 框架中RxLifecycle 绑定\r\n框架对**RxLifecycle**的实现方式 是通过接口**Lifecycleable**实现 具体实现在父类**BaseActivity**中\r\n`绑定方式`是通过`工具类` **RxLifecycleUtils**\r\n```java\r\n mModel.getUsers(lastUserId, isEvictCache)\r\n                .subscribeOn(Schedulers.io())\r\n                .compose(RxLifecycleUtils.bindToLifecycle(mRootView))//使用 Rxlifecycle,使 Disposable 和 Activity 一起销毁\r\n                .subscribe(new ErrorHandleSubscriber<List<User>>(mErrorHandler) {\r\n                 .....//省略\r\n                });\r\n```\r\n好处是解决了上面说的三个不足的地方。\r\n1. 接口实现，所以少一层继承关系\r\n2. 因为是工具类**RxLifecycle**绑定，只需要你传入一个 **IView**的接口就行,这意味着你可以在P或者其他地方直接使用。\r\n3. 工具类**RxLifecycle**绑定过程中会自动判断是**Activity**类型绑定还是**Fragment**类型绑定\r\n```java\r\n\r\n    //绑定 Activity/Fragment 的生命周期\r\n    public static <T> LifecycleTransformer<T> bindToLifecycle(@NonNull IView view) {\r\n        if (view instanceof Lifecycleable) {\r\n            return bindToLifecycle((Lifecycleable) view);\r\n        } else {\r\n            throw new IllegalArgumentException(\"view isn't Lifecycleable\");\r\n        }\r\n    }\r\n\r\n    public static <T> LifecycleTransformer<T> bindToLifecycle(@NonNull Lifecycleable lifecycleable) {\r\n        if (lifecycleable instanceof ActivityLifecycleable) {\r\n            return RxLifecycleAndroid.bindActivity(((ActivityLifecycleable) lifecycleable).provideLifecycleSubject());\r\n        } else if (lifecycleable instanceof FragmentLifecycleable) {\r\n            return RxLifecycleAndroid.bindFragment(((FragmentLifecycleable) lifecycleable).provideLifecycleSubject());\r\n        } else {\r\n            throw new IllegalArgumentException(\"Lifecycleable not match\");\r\n        }\r\n    }\r\n```\r\n---\r\n\r\n## 注意事项\r\n1. **Activity**必须继承**BaseActivity**：这个很好理解，因为对**RxLifecycle**的实际实现核心对象是在**BaseActivity**中\r\n```java\r\n    private final BehaviorSubject<ActivityEvent> mLifecycleSubject = BehaviorSubject.create();\r\n    public final Subject<ActivityEvent> provideLifecycleSubject() {\r\n        return mLifecycleSubject;\r\n    }\r\n```\r\n2. 对于第三方的Activity是无法绑定的\r\n因为你不能继承**BaseActivity**，也可以说无法实现**Lifecycleable**这个接口，\r\n\r\n3. 如果确实不能继承**BaseActivity**，该如何实现**RxLifecycle**\r\n模仿**BaseActivity** 去实现**Lifecycleable**这个接口\r\n\r\n4. **RxLifecycle** 绑定后自动取消订阅的时间（下面的方法来自RxLifecycle源码）\r\n```java\r\n    // 这个方法的含义是判断绑定的时间：如果是在Create中绑定的，那么就返回DESTROY，就是说会在onDestroy方法取消整个流的订阅\r\n    private static final Func1<ActivityEvent, ActivityEvent> ACTIVITY_LIFECYCLE =\r\n        new Func1<ActivityEvent, ActivityEvent>() {\r\n            @Override\r\n            public ActivityEvent call(ActivityEvent lastEvent) {\r\n                switch (lastEvent) {\r\n                    case CREATE:// CREATE绑定 -> DESTROY取消整个流的订阅\r\n                        return ActivityEvent.DESTROY;\r\n                    case START: // START绑定 -> STOP取消整个流的订阅\r\n                        return ActivityEvent.STOP;\r\n                    case RESUME: // RESUME绑定 -> PAUSE取消整个流的订阅\r\n                        return ActivityEvent.PAUSE;\r\n                    case PAUSE: // PAUSE绑定 -> STOP取消整个流的订阅\r\n                        return ActivityEvent.STOP;\r\n                    case STOP: // STOP绑定 -> DESTROY取消整个流的订阅\r\n                        return ActivityEvent.DESTROY;\r\n                    case DESTROY: // DESTROY -> 抛出异常（后面会处理这个异常，也会取消整个流的订阅）\r\n                        throw new OutsideLifecycleException(\"Cannot bind to Activity lifecycle when outside of it.\");\r\n                    default:\r\n                        throw new UnsupportedOperationException(\"Binding to \" + lastEvent + \" not yet implemented\");\r\n                }\r\n            }\r\n        };\r\n\r\n// 对Fragment的\r\n private static final Function<FragmentEvent, FragmentEvent> FRAGMENT_LIFECYCLE =\r\n        new Function<FragmentEvent, FragmentEvent>() {\r\n            @Override\r\n            public FragmentEvent apply(FragmentEvent lastEvent) throws Exception {\r\n                switch (lastEvent) {\r\n                    case ATTACH:\r\n                        return FragmentEvent.DETACH;\r\n                    case CREATE:\r\n                        return FragmentEvent.DESTROY;\r\n                    case CREATE_VIEW:\r\n                        return FragmentEvent.DESTROY_VIEW;\r\n                    case START:\r\n                        return FragmentEvent.STOP;\r\n                    case RESUME:\r\n                        return FragmentEvent.PAUSE;\r\n                    case PAUSE:\r\n                        return FragmentEvent.STOP;\r\n                    case STOP:\r\n                        return FragmentEvent.DESTROY_VIEW;\r\n                    case DESTROY_VIEW:\r\n                        return FragmentEvent.DESTROY;\r\n                    case DESTROY:\r\n                        return FragmentEvent.DETACH;\r\n                    case DETACH:\r\n                        throw new OutsideLifecycleException(\"Cannot bind to Fragment lifecycle when outside of it.\");\r\n                    default:\r\n                        throw new UnsupportedOperationException(\"Binding to \" + lastEvent + \" not yet implemented\");\r\n                }\r\n            }\r\n        };\r\n```  \r\n  "},"comment":{"url":"https://api.github.com/repos/JessYanCoding/MVPArms/issues/comments/451625068","html_url":"https://github.com/JessYanCoding/MVPArms/issues/177#issuecomment-451625068","issue_url":"https://api.github.com/repos/JessYanCoding/MVPArms/issues/177","id":451625068,"node_id":"MDEyOklzc3VlQ29tbWVudDQ1MTYyNTA2OA==","user":{"login":"PiPiCaptain","id":22672329,"node_id":"MDQ6VXNlcjIyNjcyMzI5","avatar_url":"https://avatars2.githubusercontent.com/u/22672329?v=4","gravatar_id":"","url":"https://api.github.com/users/PiPiCaptain","html_url":"https://github.com/PiPiCaptain","followers_url":"https://api.github.com/users/PiPiCaptain/followers","following_url":"https://api.github.com/users/PiPiCaptain/following{/other_user}","gists_url":"https://api.github.com/users/PiPiCaptain/gists{/gist_id}","starred_url":"https://api.github.com/users/PiPiCaptain/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/PiPiCaptain/subscriptions","organizations_url":"https://api.github.com/users/PiPiCaptain/orgs","repos_url":"https://api.github.com/users/PiPiCaptain/repos","events_url":"https://api.github.com/users/PiPiCaptain/events{/privacy}","received_events_url":"https://api.github.com/users/PiPiCaptain/received_events","type":"User","site_admin":false},"created_at":"2019-01-05T03:51:59Z","updated_at":"2019-01-05T03:51:59Z","author_association":"NONE","body":"@NerdAnonymous 我解决了。看了一下RxLifecycle和MVPArms源码，找到了方法。\r\nRxLifecycleUtils.bindUntilEvent(mRootView, FragmentEvent.DESTROY) 或者\r\nRxLifecycleUtils.bindUntilEvent(mRootView, ActivityEvent.DESTROY)"}}
{"actor":{"display_login":"PiPiCaptain"}}