Android rxjava和LiveData中的内存泄漏

简介: 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 大大地简化了网络操作。但是学习曲线较陡,大部分人只会一些简单的操作。

相关文章
|
25天前
|
存储 前端开发 Java
Android MVVM架构模式下如何避免内存泄漏
Android采用MVVM架构开发项目,如何避免内存泄漏风险?怎样避免内存泄漏?
79 1
|
4月前
|
Java 调度 Android开发
深入解析Android应用开发中的响应式编程与RxJava应用
在现代Android应用开发中,响应式编程及其核心框架RxJava正逐渐成为开发者的首选。本文将深入探讨响应式编程的基本概念、RxJava的核心特性以及如何在Android应用中利用RxJava提升代码的可读性和性能。 【7月更文挑战第7天】
42 1
|
6天前
|
缓存 数据处理 Android开发
在 Android 中使用 RxJava 更新 View
【10月更文挑战第20天】使用 RxJava 来更新 View 可以提供更优雅、更高效的解决方案。通过合理地运用操作符和订阅机制,我们能够轻松地处理异步数据并在主线程中进行 View 的更新。在实际应用中,需要根据具体情况进行灵活运用,并注意相关的注意事项和性能优化,以确保应用的稳定性和流畅性。可以通过不断的实践和探索,进一步掌握在 Android 中使用 RxJava 更新 View 的技巧和方法,为开发高质量的 Android 应用提供有力支持。
|
16天前
|
编解码 Android开发 UED
构建高效Android应用:从内存优化到用户体验
【10月更文挑战第11天】本文探讨了如何通过内存优化和用户体验改进来构建高效的Android应用。介绍了使用弱引用来减少内存占用、懒加载资源以降低启动时内存消耗、利用Kotlin协程进行异步处理以保持UI流畅,以及采用响应式设计适配不同屏幕尺寸等具体技术手段。
37 2
|
2月前
|
Java 测试技术 Android开发
Android性能测试——发现和定位内存泄露和卡顿
本文详细介绍了Android应用性能测试中的内存泄漏与卡顿问题及其解决方案。首先,文章描述了使用MAT工具定位内存泄漏的具体步骤,并通过实例展示了如何分析Histogram图表和Dominator Tree。接着,针对卡顿问题,文章探讨了其产生原因,并提供了多种测试方法,包括GPU呈现模式分析、FPS Meter软件测试、绘制圆点计数法及Android Studio自带的GPU监控功能。最后,文章给出了排查卡顿问题的四个方向,帮助开发者优化应用性能。
135 4
Android性能测试——发现和定位内存泄露和卡顿
|
1月前
|
设计模式 Java Android开发
安卓应用开发中的内存泄漏检测与修复
【9月更文挑战第30天】在安卓应用开发过程中,内存泄漏是一个常见而又棘手的问题。它不仅会导致应用运行缓慢,还可能引发应用崩溃,严重影响用户体验。本文将深入探讨如何检测和修复内存泄漏,以提升应用性能和稳定性。我们将通过一个具体的代码示例,展示如何使用Android Studio的Memory Profiler工具来定位内存泄漏,并介绍几种常见的内存泄漏场景及其解决方案。无论你是初学者还是有经验的开发者,这篇文章都将为你提供实用的技巧和方法,帮助你打造更优质的安卓应用。
|
2月前
|
监控 算法 数据可视化
深入解析Android应用开发中的高效内存管理策略在移动应用开发领域,Android平台因其开放性和灵活性备受开发者青睐。然而,随之而来的是内存管理的复杂性,这对开发者提出了更高的要求。高效的内存管理不仅能够提升应用的性能,还能有效避免因内存泄漏导致的应用崩溃。本文将探讨Android应用开发中的内存管理问题,并提供一系列实用的优化策略,帮助开发者打造更稳定、更高效的应用。
在Android开发中,内存管理是一个绕不开的话题。良好的内存管理机制不仅可以提高应用的运行效率,还能有效预防内存泄漏和过度消耗,从而延长电池寿命并提升用户体验。本文从Android内存管理的基本原理出发,详细讨论了几种常见的内存管理技巧,包括内存泄漏的检测与修复、内存分配与回收的优化方法,以及如何通过合理的编程习惯减少内存开销。通过对这些内容的阐述,旨在为Android开发者提供一套系统化的内存优化指南,助力开发出更加流畅稳定的应用。
67 0
|
3月前
|
编解码 Android开发 UED
【性能狂飙!】揭秘Android应用极速变身秘籍:内存瘦身+用户体验升级,打造丝滑流畅新境界!
【8月更文挑战第12天】构建高效Android应用需全方位优化,尤其重视内存管理和用户体验。通过弱引用降低内存占用,懒加载资源减少启动负担。运用Kotlin协程确保UI流畅不阻塞,响应式设计适配多屏需求。这些策略共同提升了应用性能与用户满意度。
54 1
|
3月前
|
缓存 监控 Android开发
构建高效的Android应用:从内存优化到用户体验
【7月更文挑战第57天】 在竞争激烈的移动市场中,一个高效、流畅且具有优秀用户体验的Android应用是成功的关键。本文将深入探讨如何通过内存管理和界面优化来提升应用性能,包括实用的编程技巧和策略,以及如何利用Android系统提供的工具进行调试和性能监控。读者将学习到如何识别和解决常见的性能瓶颈,以及如何设计出既美观又实用的用户界面。