RxAndroid之Rxlifecycle使用
来源:互联网 发布:c语言打开文件的路径 编辑:程序博客网 时间:2024/05/22 13:47
随着Android第三库的普及,RxJava和RxAndroid(https://github.com/ReactiveX/RxAndroid)越来越被人熟知,简洁的语法,配合Java8 Lambda表达式,使代码的结构更加清晰,通过线程调度器更容易控制和切换线程,种种优点,使用它的人也越来越多。但是使用不好,很容易导致内存泄露。Rxlifecycle (https://github.com/trello/RxLifecycle)就使被用来严格控制由于发布了一个订阅后,由于没有及时取消,导致Activity/Fragment无法销毁导致的内存泄露。
开源项目
RxLifecycle 地址:https://github.com/trello/RxLifecycle 。
该项目是为了防止RxJava中subscription导致内存泄漏而诞生的,核心思想是通过监听Activity、Fragment的生命周期,来自动断开subscription以防止内存泄漏。
Rxlifecycle使用非常方便简单,如下:
1.集成
build.gradle添加
- 1
- 2
- 3
- 4
- 5
- 6
Components包中包含RxActivity、RxFragment等等,可以用Rxlifecycle提供的,也可以自定义。
2.Sample解析
官方sample源码: 两种使用方法:
1.手动设置取消订阅的时机,例子1、例子3
2.绑定生命周期,自动取消订阅,例子2
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
注意事项
tip-1
如下代码:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
activity生命周期paused的时候
- 1
还会执行么??会会…
如果你想全部都不执行:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
tip-2
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
activity在paused的时候,
- 1
- 2
都不会执行… 而且会unsubscribe
延伸:
RxLifecycle - 当Activity被destory时自动暂停网络请求
问题
Android开发中常会有这样一个场景:
发送网络请求 -> 2. 服务器处理请求并返回数据 -> 3. client端接收数据,绘制UI。
在前两步一般都是不会出现问题的,但是在第三步,当数据返回给client端时,如果页面已经不在了,那么就无法去绘制UI,很有可能会导致意向不到的问题。因此,为了解决这个问题,一个好的思路就是当页面离开时,自动断开网络请求数据的处理过程,即数据返回后不再进行任何处理。
思考
要达到上面这样一个功能,我们可以思考,至少需要两部分:
随时监听Activity(Fragment)的生命周期并对外发射出去;
在我们的网络请求中,接收生命周期并进行判断,如果该生命周期是自己绑定的,如Destory,那么就断开数据向下传递的过程。
分析
可以看到,首先有一个核心功能要实现:就是既能够监听Activity生命周期事件并对外发射,又能够接收每一个生命周期事件并作出判断。为了实现这个功能,可以联想到RxJava中的Subject,既能够发射数据,又能够接收数据。
Subject介绍
了解Subject的读者可以跳过这部分。
如何理解Subject呢?
很容易,在RxJava里面,Observable是数据的发射者,它会对外发射数据,然后经过map、flatmap等等数据处理后,最终传递给Observer,这个数据接收者。因此,抛开中间数据处理不管,可以看出,Observable对外发射数据,是数据流的开端;Observer接收数据,是数据流的末端。
那么Subject呢?看一眼源码:
- 1
- 2
- 3
- 4
- 5
首先,它extends Observable,说明Subject具备了对外发射数据的能力,即拥有了from()、just()等等;另外,它又implements Observer,说明又能够处理数据,具备onNext()、onCompleted等等。
然后,Subject毕竟只是一个抽象类,那么我们要如何使用它呢?
这里介绍一种最简单的:PublishSubject:
- 1
- 2
- 3
- 4
- 5
- 6
这里做的事情很简单,先创建一个PublishSubject -> 绑定一个myObserver,此时subject扮演了Observable的角色,把数据发射给myObserver -> 然后subject处理接收了两个数据one、two -> 最终这些数据都传递给了myObserver。所以,subject扮演的角色是:
数据one、two => (Observer) subject (Observable) => myObserver
简单来说,我们把数据one、two塞给subject,然后subject又发射给了myObserver。
BaseActivity监听生命周期
那么我们先来实现生命周期监听功能,基本思路是:在BaseActivity里创建一
个PublishSubject对象,在每个生命周期发生时,把该生命周期事件传递给PublishSubject。具体实现如下(只写部分生命周期,其他类似):
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
这样的话,我们把所有生命周期事件都传给了lifecycleSubject了,或者说,lifecycleSubject已经接收到了并能够对外发射各种生命周期事件的能力了。
改良每一个Observable,接收生命周期并自动断开自身
通常我们的一次网络请求长这样:
- 1
- 2
其中,networkObservable表示一个通用的网络请求,会接收网络数据并传递给Observer去绘制UI。
现在,我们希望这个networkObservable监听Activity的DESTORY事件,一旦发生了DESTORY就自动断开Observer,即使网络数据回来了也不再传递给Observer去绘制UI。即:
- 1
- 2
- 3
因此,我们需要实现
- 1
这个方法,那如何实现呢?
我们知道lifecycleSubject能够发射生命周期事件了,那么我们可以让networkObservable去检查lifecycleSubject发出的生命周期,如果和自己绑定的生命周期事件一样,那就自动停掉即可。
改装networkObservable
对于networkObservable自动停掉,我们可以利用操作符
- 1
它的作用是监听otherObservable,一旦otherObservable对外发射了数据,就自动把networkObservable停掉;
那otherObservable何时对外发射数据呢?当然是lifecycleSubject发射出的生命周期事件等于绑定的生命周期事件时,开始发射。
- 1
- 2
- 3
- 4
- 5
- 6
其中的关键是判断activityLifeCycleEvent.equals(bindEvent);,一旦条件满足,otherObservable就对外发射数据,然后networkObservable就立即自动停掉。
合并 生命周期监听 与 networkObservable改良
- 在BaseActivity里添加lifecycleSubject,并把每一个生命周期事件按时传递给lifecycleSubject
- 在BaseActivity里添加一个bindUntilEvent方法:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 在任意一个网络请求 networkObservable 处改良
- 1
- 2
- 3
注意:
文中提到的networkObservable是网络请求,但实际上这不限于网络请求,任何耗时操作如文件io操作等都可以利用这个方法,来监听生命周期并自动暂停。
- RxAndroid之Rxlifecycle使用
- RxAndroid之Rxlifecycle使用
- RxAndroid之Rxlifecycle使用
- RxAndroid之Rxlifecycle使用
- RxAndroid之app的生命周期管理RxLifecycle
- Rxlifecycle使用
- RXAndroid之RxSharedPreference的使用
- Rxlifecycle使用详解
- RxLifecycle使用浅解
- Rxlifecycle使用详解
- RxAndroid+RxLifecycle+MVP实现异步请求,ButterKnife更新ui
- Android应用架构之Retrofit、RxAndroid使用
- Android 使用RxLifecycle解决RxJava内存泄漏
- Rxlifecycle生命周期的管理 配置使用
- 关于Android—>rxlifecycle的简单使用
- RxAndroid之搭建环境
- RxAndroid学习之旅
- RXAndroid Single的使用
- 【互联网人必备】最实用的6大专业搜索工具
- insmod命令
- Cannot start compiler:the SDK specified for module "IDEA".Specify the SDK at Project Structure dial
- JS——开关门
- echarts柱状图、折线图横坐标添加滚动条方法
- RxAndroid之Rxlifecycle使用
- 拉普拉斯方程之美:万物的数学之匙
- D3.js写的标签云插件
- 比尔•盖茨当选中国工程院外籍院士!(附名单)
- asp.net 报错 “C:\wxyun\System\Log\2017-11-28.System.txt”的访问被拒绝。
- 数学不好能搞人工智能吗?
- javascript 事件
- java方法的重写
- Android 使用版本控制工具时添加忽略文件的方式(详解)