Android rxjava和LiveData中的内存泄漏

最近的一个项目,是采用由RxJava、LiveData提供支持的响应式架构。尽管这些库功能强大,内存泄漏的情况;

什么是内存泄漏

内存中不再使用的对象,被另一个正在使用的对象引用,导致 GC 无法清除它并释放内存

如果我们有两个相互持有强引用的对象,即使没有任何外部引用,也会发生内存泄漏。这就是所谓的保留周期。这在 Android 上通常不是问题,因为 Java GC 使用的是标记和清除算法。

一,rxjava的内存泄漏

(1)存在内存泄漏问题

在使用rxjava的时候,如果没有及时解除订阅,在退出activity的时候,异步线程还在执行。对activity还存在引用,此时就会产生内存泄漏。

(2)常规手动取消订阅(不推荐)

为了防止内存泄漏的出现,我们需要在onDestroy取消订阅

Observable.interval(1000, TimeUnit.MILLISECONDS)
                    .subscribe(new Observer<Long>() {
                        @Override
                        public void onSubscribe(Disposable d) {
                            disposable = d;
                        }

                        @Override
                        public void onNext(Long aLong) {

                        }

                        @Override
                        public void onError(Throwable e) {

                        }

                        @Override
                        public void onComplete() {

                        }
                    });
@Override
protected void onDestroy() {

    if(disposable != null && !disposable.isDisposed()){
        //取消订阅
        disposable.dispose();
    }
    super.onDestroy();
}

以上代码的缺点很明显:

必须在onSubscribe中保存Disposable对象,然后在onDestroy方法里面取消订阅,如果有多个Observable时,很明显Disposable也会有多个,这样代码看起来紊乱,逻辑复杂,可读性差。

那么有没有什么办法对Disposable统一管理呢?

3)使用CompositeDisposable来管理Disposable

CompositeDisposable是一个存放Disposable的集合,它是一个容器,可以在BaseActivity里new一个CompositeDisposable对象,在BaseActivity的子类中可以使用该对象对Disposable统一管理。

CompositeDisposable也属于手动取消订阅,但显然比单独管理Disposable的方法强多了。

(4)RxLifecycle(自动取消订阅)(推荐)
Observable
      .interval(1000, TimeUnit.MILLISECONDS)
      .compose(this.<Long>bindUntilEvent(ActivityEvent.DESTROY))
      .subscribe(new Consumer<Long>() {
          @Override
          public void accept(Long aLong) throws Exception {
          Log.d("aaa", String.valueOf(aLong));
          }
      });

RxLifecycle将Observable和Activity(Fragment)的生命周期绑定在一起,使用compose关键字来确定Observable将要在哪个生命周期执行时自动取消订阅

(5)AutoDispose(自动取消订阅)(推荐)

Observable
                    .interval(1000, TimeUnit.MILLISECONDS)
                    //AutoDispose的关键语句
                    .as(AutoDispose.<Long>autoDisposable(AndroidLifecycleScopeProvider.from(this)))
                    .subscribe(new Consumer<Long>() {
                        @Override
                        public void accept(Long aLong) throws Exception {
                            Log.d("aaa", String.valueOf(aLong));
                        }
                    });

AutoDispose要比RxLifecycle更加简单,有人说使用AutoDispose取代RxLifecycle也是有一定道理的,毕竟RxLifecycle需要继承对应的RxActivity、RxFragment,而AutoDispose却不用

二,LiveData可能产生的泄漏分析

订阅LiveData错误使用context

有一个RecyclerView通过. 渲染 a 的片段Adapter。您将如何观察项目列表并更新Adapter? 通常你会在你的订阅中拥有一个LiveData项目,然后使用.ViewModelDiffUtil

但是您会在哪里定义该订阅?有两种可能的选择:您可以在片段中创建订阅,然后将更新的项目列表发送到Adapter,或者您可以将您的传递ViewModel给Adapter并Adapter直接观察更改.

最后,LiveData 与 RxJava

虽然 LiveData 和 RxJava 都属于观察者模式的实现,但是他们的本质是完全不同的。

LiveData 只是数据的储存类,本身不支持复杂的线程操作和事件序列,也没有异常处理。与 RxJava 相比,具有体积小,学习成本低等优点。

RxJava 是一个完整的基于事件的观察序列,用来处理异步操作的框架。使用 RxJava 可以方便的切换线程,同时 RxJava 拥有的众多操作符也可以让逻辑变的清晰可循。配合 Retrofit 大大地简化了网络操作。但是学习曲线较陡,大部分人只会一些简单的操作。

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Android Repository是一种用于处理数据源的设计模式,在Android开发广泛使用。它的主要目的是将数据源(例如数据库、网络请求等)与UI层分离开来,实现更好的代码组织和结构。使用Android Repository模式,我们可以将数据的获取、存储和管理逻辑从UI层分离出来,使得UI层只负责展示数据,而数据的获取和存储则由Repository负责。 RxJava是一种响应式编程库,它提供了一种优雅和强大的方式来处理异步事件流。通过使用Observable和Observer的概念,我们可以将事件流转换成链式的操作符来处理和组合数据。RxJava可以让我们更容易地进行异步编程,并且具有线程切换、错误处理、背压等优秀的特性。 LiveDataAndroid Jetpack组件的一部分,用于解决UI数据和生命周期的关联问题。LiveData具有生命周期感知能力,当数据发生变化时,它会自动通知相关观察者进行更新。LiveData可以确保在合适的时间和生命周期下更新UI,避免了内存泄漏和空指针异常等问题。 使用RxJavaLiveData可以将数据源的异步操作与UI层分离开来。在Android开发,我们经常需要进行异步操作,例如进行网络请求或数据库查询。使用RxJava可以让我们更方便地处理这些异步操作,在链式的操作符进行数据的变换、过滤和组合等操作。 然后,利用LiveData可以将异步操作的结果通知给UI层。LiveData具有生命周期感知能力,当Activity或Fragment处于活跃状态时,LiveData会通知相关观察者进行数据更新,从而保证数据的正确显示。 综上所述,结合Android Repository、RxJavaLiveData可以实现一套完整的、优雅的异步操作和UI更新的方案。这些组件的结合使用可以提高开发效率,降低代码的复杂度,并且保证了数据的正确和一致性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

码农乐园

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值