RxJava 和 RxAndroid 三(生命周期控制和内存优化)
前言:对Rxjava、Rxandroid不了解的同学可以先看看
RxJava 和 RxAndroid
RxJava 和 RxAndroid 二(操作符的使用)
RxJava使我们很方便的使用链式编程,代码看起来既简洁又优雅。但是RxJava使用起来也是有副作用的,使用越来越多的订阅,内存开销也会变得很大,稍不留神就会出现内存溢出的情况,这篇文章就是介绍Rxjava使用过程中应该注意的事项。
1、取消订阅 subscription.unsubscribe() ;
package lib.com.myapplication;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import rx.Observable;
import rx.Subscription;
import rx.functions.Action1;
public class MainActivity extends AppCompatActivity {
Subscription subscription ;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
subscription = Observable.just( "123").subscribe(new Action1<String>() {
@Override
public void call(String s) {
System.out.println( "tt--" + s );
}
}) ;
}
@Override
protected void onDestroy() {
super.onDestroy();
//取消订阅
if ( subscription != null ){
subscription.unsubscribe();
}
}
}
2、线程调度
Scheduler调度器,相当于线程控制器
Schedulers.immediate(): 直接在当前线程运行,相当于不指定线程。这是默认的 Scheduler。Schedulers.newThread():总是启用新线程,并在新线程执行操作.Schedulers.io():I/O 操作(读写文件、读写数据库、网络信息交互等)所使用的 Scheduler。行为模式和 newThread() 差不多,区别在于 io() 的内部实现是是用一个无数量上限的线程池,可以重用空闲的线程,因此多数情况下 io() 比 newThread() 更有效率。不要把计算工作放在 io() 中,可以避免创建不必要的线程。Schedulers.computation(): 计算所使用的 Scheduler。这个计算指的是 CPU 密集型计算,即不会被 I/O 等操作限制性能的操作,例如图形的计算。这个 Scheduler 使用的固定的线程池,大小为 CPU 核数。不要把 I/O 操作放在 computation() 中,否则 I/O 操作的等待时间会浪费 CPU。还有RxAndroid里面专门提供了
AndroidSchedulers.mainThread(),它指定的操作将在 Android 主线程运行。
常见的场景:为了不阻塞UI,在子线程加载数据,在主线线程显示数据
Observable.just( "1" , "2" , "3" )
.subscribeOn(Schedulers.io()) //指定 subscribe() 发生在 IO 线程
.observeOn( AndroidSchedulers.mainThread() ) //指定 Subscriber 的回调发生在主线程
.subscribe(new Action1<String>() {
@Override
public void call(String s) {
textView.setText( s );
}
}) ;
上面这段代码,数据"1"、"2"、"3"将在io线程中发出,在android主线程中接收数据。这种【后台获取数据,前台显示数据】模式适用于大多数的程序策略。
Scheduler 自由多次切换线程。恩,这个更为牛逼
Observable.just(1, 2, 3, 4) // IO 线程,由 subscribeOn() 指定
.subscribeOn(Schedulers.io())
.observeOn(Schedulers.newThread())
.map(mapOperator) // 新线程,由 observeOn() 指定
.observeOn(Schedulers.io())
.map(mapOperator2) // IO 线程,由 observeOn() 指定
.observeOn(AndroidSchedulers.mainThread)
.subscribe(subscriber); // Android 主线程,由 observeOn() 指定
从上面的代码可以看出
observeOn()可以调用多次来切换线程,observeOn 决定他下面的方法执行时所在的线程。subscribeOn()用来确定数据发射所在的线程,位置放在哪里都可以,但它是只能调用一次的。
上面介绍了两种控制Rxjava生命周期的方式,第一种:取消订阅 ;第二种:线程切换 。这两种方式都能有效的解决android内存的使用问题,但是在实际的项目中会出现很多订阅关系,那么取消订阅的代码也就越来越多。造成了项目很难维护。所以我们必须寻找其他可靠简单可行的方式,也就是下面要介绍的。
3、rxlifecycle 框架的使用
github地址: https://github.com/trello/RxLifecycle
在android studio 里面添加引用
compile 'com.trello:rxlifecycle-components:0.6.1'让你的activity继承
RxActivity,RxAppCompatActivity,RxFragmentActivity
让你的fragment继承RxFragment,RxDialogFragment;下面的代码就以RxAppCompatActivity举例bindToLifecycle方法
在子类使用Observable中的compose操作符,调用,完成Observable发布的事件和当前的组件绑定,实现生命周期同步。从而实现当前组件生命周期结束时,自动取消对Observable订阅。public class MainActivity extends RxAppCompatActivity {
TextView textView ; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView = (TextView) findViewById(R.id.textView); //循环发送数字
Observable.interval(0, 1, TimeUnit.SECONDS)
.subscribeOn( Schedulers.io())
.compose(this.<Long>bindToLifecycle()) //这个订阅关系跟Activity绑定,Observable 和activity生命周期同步
.observeOn( AndroidSchedulers.mainThread())
.subscribe(new Action1<Long>() {
@Override
public void call(Long aLong) {
System.out.println("lifecycle--" + aLong);
textView.setText( "" + aLong );
}
});
}
}
上面的代码是Observable循环的发送数字,并且在textview中显示出来
1、没加compose(this.<Long>bindToLifecycle())当Activiry 结束掉以后,Observable还是会不断的发送数字,订阅关系没有解除
2、添加compose(this.<Long>bindToLifecycle())当Activity结束掉以后,Observable停止发送数据,订阅关系解除。从上面的例子可以看出
bindToLifecycle()方法可以使Observable发布的事件和当前的Activity绑定,实现生命周期同步。也就是Activity 的 onDestroy() 方法被调用后,Observable 的订阅关系才解除。那能不能指定在Activity其他的生命状态和订阅关系保持同步,答案是有的。就是bindUntilEvent()方法。这个逼装的好累!bindUntilEvent( ActivityEvent event)ActivityEvent.CREATE: 在Activity的onCreate()方法执行后,解除绑定。ActivityEvent.START:在Activity的onStart()方法执行后,解除绑定。ActivityEvent.RESUME:在Activity的onResume()方法执行后,解除绑定。ActivityEvent.PAUSE: 在Activity的onPause()方法执行后,解除绑定。ActivityEvent.STOP:在Activity的onStop()方法执行后,解除绑定。ActivityEvent.DESTROY:在Activity的onDestroy()方法执行后,解除绑定。
//循环发送数字
Observable.interval(0, 1, TimeUnit.SECONDS)
.subscribeOn( Schedulers.io())
.compose(this.<Long>bindUntilEvent(ActivityEvent.STOP )) //当Activity执行Onstop()方法是解除订阅关系
.observeOn( AndroidSchedulers.mainThread())
.subscribe(new Action1<Long>() {
@Override
public void call(Long aLong) {
System.out.println("lifecycle-stop-" + aLong);
textView.setText( "" + aLong );
}
});
经过测试发现,当Activity执行了onStop()方法后,订阅关系已经解除了。
上面说的都是订阅事件与Activity的生命周期同步,那么在Fragment里面又该怎么处理的?FragmentEvent这个类是专门处理订阅事件与Fragment生命周期同步的大杀器public enum FragmentEvent { ATTACH,
CREATE,
CREATE_VIEW,
START,
RESUME,
PAUSE,
STOP,
DESTROY_VIEW,
DESTROY,
DETACH
}
可以看出
FragmentEvent和ActivityEvent类似,都是枚举类,用法是一样的。这里就不举例了!
总结
1、这三篇文章的相关代码示例都在 http://git.oschina.net/zyj1609/RxAndroid_RxJava
2、通过上面的三种方法,我相信你在项目中使用Rxjava的时候,已经能够很好的控制了 Rxjava对内存的开销。如果你有其他的方法或者问题,可以留言给我。
RxJava 和 RxAndroid 四(RxBinding的使用)
RxJava 和 RxAndroid 三(生命周期控制和内存优化)的更多相关文章
- RxJava 和 RxAndroid (生命周期控制和内存优化)
RxJava使我们很方便的使用链式编程,代码看起来既简洁又优雅.但是RxJava使用起来也是有副作用的,使用越来越多的订阅,内存开销也会变得很大,稍不留神就会出现内存溢出的情况,这篇文章就是介绍Rxj ...
- UIViewController生命周期控制
UIViewController生命周期控制 UIViewController介绍 官方的介绍例如以下 The UIViewController class provides the fundamen ...
- Newbe.Claptrap 框架如何实现多级生命周期控制?
Newbe.Claptrap 框架如何实现多级生命周期控制?最近整理了一下项目的术语表.今天就谈谈什么是 Claptrap Lifetime Scope. 特别感谢 kotone 为本文提供的校对建议 ...
- Vue.js 子组件的异步加载及其生命周期控制
前端开发社区的繁荣,造就了很多优秀的基于 MVVM 设计模式的框架,而组件化开发思想也越来越深入人心.这其中不得不提到 Vue.js 这个专注于 VM 层的框架. 本文主要对 Vue.js 组件化开发 ...
- vue学习三:生命周期钩子
生命周期钩子介绍: 每个 Vue 实例在被创建时都要经过一系列的初始化过程——例如,需要设置数据监听.编译模板.将实例挂载到 DOM 并在数据变化时更新 DOM 等.同时在这个过程中也会运行一些叫做生 ...
- 管中窥豹——从对象的生命周期梳理JVM内存结构、GC调优、类加载、AOP编程及性能监控
如题,本文的宗旨既是透过对象的生命周期,来梳理JVM内存结构及GC相关知识,并辅以AOP及双亲委派机制原理,学习不仅仅是海绵式的吸收学习,还需要自己去分析why,加深对技术的理解和认知,祝大家早日走上 ...
- Docker 基本概念(三)-生命周期详解(镜像、容器、仓库)
Docker三大组件:镜像.容器.仓库. 一.镜像 1 从仓库获取镜像 #一.从仓库获取镜像,帮助命令:docker pull -help 命令:docker pull [选项] [docker R ...
- UIViewController生命周期控制-开发规范
从网上各位iOS们收集并总结: 各方法使用: init 中初始化一些UI组件,比如UIButton,UILabel等 loadView 中 createFields 接受参数,初始化变量 create ...
- iOS UIViewController生命周期控制
具体流程,看下图: init方法在init方法中实例化必要的对象(遵从LazyLoad思想)init方法中初始化ViewController本身 loadView方法当view需要被展示而它却是nil ...
随机推荐
- 第1/24周 SQL Server 如何执行一个查询
大家好,欢迎来到第1周的SQL Server性能调优培训.在我们进入SQL Server性能调优里枯燥难懂的细节内容之前,我想通过讲解SQL Server如何执行一个查询来建立基础.这个部分非常重要, ...
- Java魔法堂:JVM的运行模式
一.前言 JVM有Client和Server两种运行模式.不同的模式对应不同的应用场景,而JVM也会有相应的优化.本文将记录JVM模式的信息,以便日后查阅. 二.介绍 在$JAVA_HOME/jre/ ...
- Moon.Orm3.8技术全攻略
Moon.ORM技术全攻略 一.绪论 本文主要是针对Moon.ORM的技术的讨论及其使用使用指导.如有其它疑问,请留言.本文主要针对Moon.ORM3.9版本,同时将会对4.0做一个技术预览.本文从 ...
- Hibernate —— Hibernate 配置文件
1.Hibernate 配置文件主要用于配置**数据库连接**和 Hibernate 运行时所需的**各种属性**. 2.每一个 Hibernate 配置文件对应一个 Configuration 对象 ...
- Fundamentals of MVC
Chapter 1 Fundamentals of MVC Microsoft's Web Development Platforms Understanding the past can b ...
- 数据结构(C语言第2版)----时间复杂度和单链表
马上要到校招了,复习下相关的基础知识. 时间复杂度是什么? 官方解释: 算法的执行时间需要依据算法所编制的程序在计算机上于运行时所消耗的时间来度量.在算法中可以使用基本的语句的执行次数作为算法的时间复 ...
- C语言学习015:联合(union)与枚举(enum)
联合 联合和结构的区别是,结构会为每个字段申请一片内存空间,而联合只是申请了一片内存空间然后所有字段都会保存到这片空间中,这片空间的大小由字段中最长的决定,下面我们就开始定义一个联合 //联合的定义 ...
- HTTP & HTTPs
HTTP HTTP 消息 HTTP 方法 参考 [1]. HTTP 协议初识 - 阮一峰: HTTPS 参考 [1]. HTTPS 升级指南 - 阮一峰:
- PHP程序员7小时学会Kotlin系列 - 第一小时 背景
基础知识 Kotlin简单的说是Java语言的改良版本,是一种静态类型编程语言,可运行于JVM.Andoid或JavaScript环境,于2016年2月15日发布1.0正式版.Kotlin定位于一门通 ...
- 第 17 章 CSS 边框与背景[下]
学习要点: 1.设置背景 主讲教师:李炎恢 本章主要探讨 HTML5 中 CSS 边框和背景,通过边框和背景的样式设置,给元素增加更丰富的外观. 一.设置背景 盒模型的尺寸可以通过两种方式实现可见性, ...