动手实现一个轻量级无侵入性的RxJava自动注销库RxLifecycle

RxLifecycle是一个低侵入性的RxJava注销管理库,无需改变Activity的继承结构,支持自动注销,适用于包括自定义View在内的多种场景。通过注入RxLifecycle并使用compose操作符配合LifecycleTransformer,可以方便地管理RxJava的生命周期,避免内存泄漏。文章详细解释了库的工作原理,包括使用BehaviorSubject跟踪Activity生命周期,并通过takeUntil操作符实现自动注销。
摘要由CSDN通过智能技术生成

*本篇文章已授权微信公众号 guolin_blog (郭霖)独家发布

一. 概述

RxLifecycle是一个轻量级,侵入性低的RxJava注销管理库.他不会改变原有项目Activity的继承结构,轻松实现RxJava在Android平台下的自动注销,甚至你在自定义view的时候使用RxJava都能轻松完整自动注销功能.如果你的项目在开发中期想要引入RxJava相关的自动注销库,这个库将是你不错的选择,原因就在他的入侵性低.

项目地址: 欢迎star

https://github.com/dhhAndroid/RxLifecycle

gradle 依赖:

compile ‘com.dhh:rxlifecycle:1.5’

二. 使用方法(请查看github主页,因为版本迭代,使用方法有所不同)

把RxLifecycle注入到Activity,请放心,RxLifecycle库并不会引用with()传进去的上下文引用,所以不用反注销,不会造成内存泄漏,这块的逻辑类似Glide的处理方式,在原理解析部分会讲到.以下两种注入方式,实现一种即可:

如果你有一个BaseActivity,仅需在BaseActivity的onCreate方法里注入RxLifecycle:


        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            RxLifecycle.injectRxLifecycle(this);

        }

既然你有一个BaseActivity,可以将RxLifecycle代码封装一下:


        private <T> LifecycleTransformer<T> bindToLifecycle() {
            return RxLifecycle.with(this).bindToLifecycle();
        }

        private <T> LifecycleTransformer<T> bindOnDestroy() {
            return RxLifecycle.with(this).bindOnDestroy();
        }

        private <T> LifecycleTransformer<T> bindUntilEvent(ActivityEvent event) {
            return RxLifecycle.with(this).bindUntilEvent(event);
        }

        //use
        @Override
        protected void onStart() {
            super.onStart();
            Observable.just(1)
                    //use       
                    .compose(bindToLifecycle())
                    .subscribe();
        }

或者你已经有了继承Application的操作,你也可以这样注入RxLifecycle:


        public class RxLifecycleAPP extends Application {
   
            @Override
            public void onCreate() {
                super.onCreate();
                RxLifecycle.injectRxLifecycle(this);
            }
        }

注意:

1. 以上两种注入RxLifecycle的方式,实现一种就可以了,同时实现也没有问题,如果你乐意!

2. 如果你不在Activity的”onPause”生命周期及其以后的生命周期里订阅一个Observable,注入RxLifecycle的步骤可以省略不做.如果在Activity的”onPause”生命周期及其以后的生命周期里订阅一个Observable,并且使用RxLifecycle.with(this).bindToLifecycle(),必须进行RxLifecycle注入步奏.在原理解析部分会说明导致这种问题的原因.代码示例:


    @Override
    protected void onPause() {
        super.onPause();
        Observable.just("dhhAndroid")
                //其他方式绑定不用预先注入
                .compose(RxLifecycle.with(this).<String>bindOnDestroy())
                .subscribe();
        Observable.just(1)
                //在onPause及其以后生命周期,使用bindToLifecycle()必须先注入RxLifecycle
                .compose(RxLifecycle.with(this).<Integer>bindToLifecycle())
                .subscribe();
    }

3. 为了简化和保险,可以忽略第二条,全部注入,第二条就当我在瞎BB……

在Activity和Fragment中使用:

仅仅需要在你原先的Observable事件流上用compose操作符加上如下代码:

        Observable.timer(10, TimeUnit.SECONDS)
                //自动判断生命周期
                .compose(RxLifecycle.with(this).<Long>bindToLifecycle())
                .subscribe();

        Observable.timer(10, TimeUnit.SECONDS)
                //当activity onStop 注销
                .compose(RxLifecycle.with(this).<Long>bindUntilEvent(ActivityEvent.onStop))
                .subscribe();
        Observable.just("dhhAndroid")
                //当activity onDestroy 注销
                .compose(RxLifecycle.with(this).<String>bindOnDestroy())
                .subscribe();

RxLifecycle.with(),with方法可以接收的参数类型有Activity,Context(说明:这个Context必须能强转成Activity),View,Fragment,V4.Fragment等.

在自定义view用使用

如果你在自定义view的时候里面使用的RxJava,以及View内部有retrofit+RxJava的网络访问,已经RxJava操作的耗时数据转换,同样支持一行代码管理RxJava自动注销.用法和在activity和fragment里一样:


        public class MyView extends View {
   
            //other...

            public void doSomething(){
                Observable.timer(10, TimeUnit.SECONDS)
                        //自动判断生命周期
                        .compose(RxLifecycle.with(this).<Long>bindToLifecycle())
                        .subscribe();

                Observable.timer(10, TimeUnit.SECONDS)
                        //当activity onStop 注销
                        .compose(RxLifecycle.with(this).<Long>bindUntilEvent(ActivityEvent.onStop))
                        .subscribe();
                Observable.just("dhhAndroid")
                        //当activity onDestroy 注销
                        .compose(RxLifecycle.with(this).<String>bindOnDestroy())
                        .subscribe();
                ....
            }       
        }

在其他层使用

在MVP架构或者其他地方使用RxLifecycle时,仅需确保所使用的地方能获取到一个能转化成Activity的Context即可. 项目里我写了一个with重载方法可传入任意对象,只要能转化成Context,或者通过反射能获取到所传对象的成员变量有能转化成Context(Activity),也可实现RxJava生命周期自动绑定,但考虑到性能问题暂未开放(private方法).你可以根据这用思路,结合自己项目进行扩展.代码如下:


    private static LifecycleManager with(Object object) {
        if (object instanceof Context) {
            return with((Context) object);
        }
        for (Field field : object.getClass().getDeclaredFields()) {
            try {
                field.setAccessible(true);
                Object value = field.get(object);
                if (value instanceof Context) {
                    return with((Context) value);
                }

            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        }
        throw new ClassCastException(object.getClass().getSimpleName() + " can\'t convert Context !");
    }

三 . 原理解析(开始秀操作了,别打我)

首先聊一下

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值