前言
1.此处主要是基于RxJava2.0的解析
2.讲解内容包括 基本介绍 原理 具体使用
一、定义
RxJava在GitHub中的介绍:
https://github.com/ReactiveX/RxJava/wiki
//RxJava主页地址:https://github.com/ReactiveX/RxJava/wiki
RxJava is a Java VM implementation of ReactiveX (Reactive Extensions): a library for composing asynchronous and event-based programs by using observable sequences.
// 翻译:RxJava 是ReactiveX (Reactive Extensions)在JavaVM上使用Observable序列组合异步和基于事件的程序的库。
RxJava is Lightweight
RxJava tries to be very lightweight. It is implemented as a single JAR that is focused on just the Observable abstraction and related higher-order functions.
// 翻译:RxJava尽力做到非常轻巧。它仅关注Observable的抽象和与之相关的高层函数,实现为一个单独的JAR文件。
总结:RxJava 是一个 基于事件流、实现异步操作 的库
二、作用
主要用于异步操作的实现
Android中实现异步的方式:
Java方法来实现异步:
1、继承Thread类
2、实现Runnable接口
Android 的方法实现异步:
1、Handler
2、AsyncTask
3、RxJava
用Java方法来实现异步:
主要有两种方法来实现异步,继承Thread类和实现Runnable接口
1、继承Thread类
private void asynThread() {
AsynThread asynThread = new AsynThread("asynThread");
asynThread.start();
}
public class AsynThread extends Thread {
private String name;
public AsynThread(String name) {
this.name = name;
}
@Override
public void run() {
runOnUiThread(new Runnable() {
@Override
public void run() {
//ui更新
tv_content.setText(name);
}
});
}
}
2、实现Runnable接口
private void asynThreadRunable() {
AsynThreadRunable asynThreadRunable = new AsynThreadRunable("asynThreadRunable");
Thread thread = new Thread(asynThreadRunable);
thread.start();
}
public class AsynThreadRunable implements Runnable{
private String name;
public AsynThreadRunable(String name) {
this.name = name;
}
@Override
public void run() {
Log.d("AsynThreadRunable",name);
runOnUiThread(new Runnable() {
@Override
public void run() {
//ui更新
tv_content.setText(name);
}
});
}
}
private void asynThreadRunableInner(){
//或者直接使用内部类:
new Thread(new Runnable(){
@Override
public void run(){
Log.d("asynThreadRunableInner","执行耗时或者异步操作:");
runOnUiThread(new Runnable() {
@Override
public void run() {
//ui更新
tv_content.setText("asynThreadRunableInner");
}
});
}
}).start();
}
Android的方法实现异步:
1、Handler
Handler 用来解决线程间通信,可以在子线程中提醒UI线程更新组件
private void aysnHandler(){
new Thread(new Runnable(){
@Override
public void run() {
//在子线程中执行耗时任务,执行完毕后需要通过 Handler 通知UI线程更新UI
mHandler.sendEmptyMessage(0);
}
}).start();
}
Handler mHandler = new Handler(){
@Override
public void handleMessage(Message mas){
switch(mas.what){
case 0:
//此处进行UI的更新
tv_content.setText("aysnHandler");
break;
}
}
};
主线程也可以给子线程发消息:
private void aysnMyHandler(){
final MyThread myThread = new MyThread();
myThread.start();
//发消息到目标子线程
tv_content.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
myThread.mMyHandler.obtainMessage(0).sendToTarget();
}
});
}
public class MyThread extends Thread{
public Handler mMyHandler;
@Override
public void run() {
super.run();
//1.建立消息循环,初始化Looper
Looper.prepare();
mMyHandler = new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
int what = msg.what;
if(what == 0){
runOnUiThread(new Runnable() {
@Override
public void run() {
tv_content.setText("发消息到目标子线程");
}
});
}
}
};
//启动消息循环
Looper.loop();
}
}
2、AsyncTask
使用AsyncTask来实现异步简单便携,各个过程都有明确的回调,过程可控,但是缺点就是要是执行多个异步,就会变得很复杂
private void asynAsynTask(){
MyAsyncTask myAsyncTask = new MyAsyncTask();
myAsyncTask.execute("http://www.baidu.com/xxx.jpg");
}
class MyAsyncTask extends AsyncTask<String, Integer,String> {
@Override
protected void onPreExecute() {
//这里是开始线程之前执行的,是在UI线程
super.onPreExecute();
}
@Override
protected String doInBackground(String... params){
//这是在后台子线程中执行的
String url = params[0];
return url;
}
@Override
protected void onCancelled(){
//当任务被取消时回调
super.onCancelled();
}
@Override
protected void onProgressUpdate(Integer... values){
super.onProgressUpdate(values);
//更新进度
}
@Override
protected void onPostExecute(String url){
super.onPostExecute(url);
//当任务执行完成时调用,在UI线程
tv_content.setText(url);
}
}
3、RxJava
private void aysnRxJava(){
Observable.create(new ObservableOnSubscribe<Integer>() {
// 1. 创建被观察者 & 生产事件
@Override
public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
emitter.onNext(1);
emitter.onNext(2);
emitter.onNext(3);
emitter.onComplete();
}
}).subscribe(new Observer<Integer>() {
// 2. 通过通过订阅(subscribe)连接观察者和被观察者
// 3. 创建观察者 & 定义响应事件的行为
@Override
public void onSubscribe(Disposable d) {
Log.d("TAG", "开始采用subscribe连接");
}
// 默认最先调用复写的 onSubscribe()
@Override
public void onNext(Integer value) {
Log.d("TAG", "对Next事件"+ value +"作出响应" );
}
@Override
public void onError(Throwable e) {
Log.d("TAG", "对Error事件作出响应");
}
@Override
public void onComplete() {
Log.d("TAG", "对Complete事件作出响应");
}
});
}
三、特点
3.1、 Handler异步实现的原理和使用的优缺点
在Handler 异步实现时,涉及到 Handler, Looper, Message,Thread四个对象,实现异步的流程是主线程启动Thread(子线程)àthread(子线程)运行并生成Message- àLooper获取Message并传递给HandleràHandler逐个获取Looper中的Message,并进行UI变更。
使用的优点:
结构清晰,功能定义明确
对于多个后台任务时,简单,清晰
3.2、AsyncTask实现的原理,和适用的优缺点
AsyncTask,是android提供的轻量级的异步类,可以直接继承AsyncTask,在类中实现异步操作,并提供接口反馈当前异步执行的程度(可以通过接口实现UI进度更新),最后反馈执行的结果给UI主线程.
使用的优点:
简单,快捷
过程可控
使用的缺点:
在使用多个异步操作和并需要进行Ui变更时,就变得复杂起来.
3.3、RxJava特点
RxJava的使用方式是:基于事件流的链式调用,所以使得 RxJava:
逻辑简洁
实现优雅
使用简单
更重要的是,随着程序逻辑的复杂性提高,仍然能够保持简洁,优雅,兼顾了Handler和AsyncTask所有优点
四、原理
从上段RxJava代码的实现上可以总结出如下执行示意图:
RxJava可以看做是一种扩展的观察者模式
RxJava的扩展观察者模式中有4个角色:
角色 | 作用 |
---|---|
被观察者(Observable) | 产生事件 |
观察者(Observer) | 接收事件,并给出响应动作 |
订阅(Subscribe) | 连接 被观察者 & 观察者 |
事件(Event) | 被观察者 & 观察者 沟通的载体 |
总结:
被观察者 (Observable) 通过 订阅(Subscribe) 按顺序发送事件给观察者(Observer), 观察者(Observer) 按顺序接收事件 & 作出对应的响应动作
五、源码分析
private void aysnRxJava(){
Observable.create(new ObservableOnSubscribe<Integer>() {
// 1. 创建被观察者 & 生产事件
@Override
public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
emitter.onNext(1);
emitter.onNext(2);
emitter.onNext(3);
emitter.onComplete();
}
}).subscribe(new Observer<Integer>() {
// 2. 通过通过订阅(subscribe)连接观察者和被观察者
// 3. 创建观察者 & 定义响应事件的行为
@Override
public void onSubscribe(Disposable d) {
Log.d("TAG", "开始采用subscribe连接");
}
// 默认最先调用复写的 onSubscribe()
@Override
public void onNext(Integer value) {
Log.d("TAG", "对Next事件"+ value +"作出响应" );
}
@Override
public void onError(Throwable e) {
Log.d("TAG", "对Error事件作出响应");
}
@Override
public void onComplete() {
Log.d("TAG", "对Complete事件作出响应");
}
});
}
结合上面代码和使用步骤带着问题一起来了解下RxJava运行的流程:
Rxjava如何创建事件源、发射事件、何时发射事件、如何将观察者和被观察者关联起来
1、Observable
Observable是事件生产者,定义需发送的事件
a、首先来分析事件是如何生成的,直接看代码 Observable.create()方法。
@CheckReturnValue
@NonNull
@SchedulerSupport(SchedulerSupport.NONE)
//方法中传入的 ObservableOnSubscribe是个接口,只包含subscribe方法,这里就是事件生产的源头。
public static <T> Observable<T> create(ObservableOnSubscribe<T> source) {
//判空操作
ObjectHelper.requireNonNull(source, "source is null");
//这里是重头戏,return了说明这里生产了Observable
return RxJavaPlugins.onAssembly(new ObservableCreate<T>(source));
}
RxJavaPlugins.onAssembly(new ObservableCreate<T>(source));return了说明这里生产了Observable的。继续跟踪进去
/**
* Calls the associated hook function.
* @param <T> the value type
* @param source the hook's input value
* @return the value returned by the hook
*/
@SuppressWarnings({ "rawtypes", "unchecked" })
@NonNull
public static <T> Observable<T> onAssembly(@NonNull Observable<T> source) {
Function<? super Observable, ? extends Observable> f = onObservableAssembly;
if (f != null) {
return apply(f, source);
}
return source;
}
根据注释可以看出该方法是hook function 称为钩子函数,分析代码中静态对象onObservableAssembly默认为null, 所以此方法直接返回传入的参数source。
onObservableAssembly可以通过静态方法RxJavaPlugins. setOnObservableAssembly ()设置全局的Hook函数
//提取与onObservableAssembly有关的代码
public final class RxJavaPlugins {
@SuppressWarnings("rawtypes")
@Nullable
static volatile Function<? super Observable, ? extends Observable> onObservableAssembly;
//set方法
public static void setOnObservableAssembly(@Nullable Function<? super Observable, ? extends Observable> onObservableAssembly) {
if (lockdown) {
throw new IllegalStateException("Plugins can't be changed anymore");
}
RxJavaPlugins.onObservableAssembly = onObservableAssembly;
}
//get方法
public static Function<? super Observable, ? extends Observable> getOnObservableAssembly() {
return onObservableAssembly;
}
//方法的使用入口
public static <T> Observable<T> onAssembly(@NonNull Observable<T> source) {
Function<? super Observable, ? extends Observable> f = onObservableAssembly;
if (f != null) {
return apply(f, source);
}
return source;
}
}
至此我们明白了,事件的源就是new ObservableCreate()对象,将ObservableOnSubscribe作为参数传递给ObservableCreate的构造函数。事件是由接口ObservableOnSubscribe的subscribe方法上产的,至于何时生产事件,我们继续分析。
b、Observable是何时生产事件的,进入ObservableCreate分析
/**
* 源码分析:Observable.create(new ObservableOnSubscribe<Integer>(){...})
**/
public static <T> Observable<T> create(ObservableOnSubscribe<T> source) {
...
// 仅贴出关键源码,根据上面分析这里return相当于下面代码
return new ObservableCreate<T>(source);
// 创建ObservableCreate类对象 ->>分析1
// 注:传入source对象(即 我们手动创建的ObservableOnSubscribe对象)
}
/**
* 分析1:new ObservableCreate<T>(source)
* 这里只贴出部分需要分析的代码
**/
// 通过extends Observable得知ObservableCreate类 就是 Observable的子类
public final class ObservableCreate<T> extends Observable<T> {
final ObservableOnSubscribe<T> source;
// 构造函数
// 传入了传入source对象 = 我们手动创建的ObservableOnSubscribe对象
public ObservableCreate(ObservableOnSubscribe<T> source) {
this.source = source;
}
/**
*重写了subscribeActual方法
*跟踪进去发现该方法是Observable执行subscribe订阅时执行的方法,所以只有执行subscribe时才会触发;
*得出结论:Observable是何时生产事件的,就是在Observable执行subscribe订阅时触发的
*
**/
@Override
protected void subscribeActual(Observer<? super T> observer) {
// 1. 创建1个CreateEmitter对象(封装成1个Disposable对象)
// 作用:发射事件
CreateEmitter<T> parent = new CreateEmitter<T>(observer);
// 2. 调用观察者(Observer)的onSubscribe()
// onSubscribe()的实现 = 使用步骤的第2步(创建观察者(Observer))时复写的onSubscribe()
observer.onSubscribe(parent);
try {
// 3. 调用source对象的subscribe()
// source对象 = 使用步骤1(创建被观察者(Observable))中创建的ObservableOnSubscribe对象
// subscribe()的实现 = 使用步骤1(创建被观察者(Observable))中复写的subscribe()
source.subscribe(parent);
} catch (Throwable ex) {
Exceptions.throwIfFatal(ex);
parent.onError(ex);
}
}
// onNext()源码分析
static final class CreateEmitter<T>
extends AtomicReference<Disposable>
implements ObservableEmitter<T>, Disposable {
private static final long serialVersionUID = -3434801548987643227L;
final Observer<? super T> observer;
CreateEmitter(Observer<? super T> observer) {
this.observer = observer;
}
@Override
public void onNext(T t) {
// 注:发送的事件不可为空
if (t == null) {
onError(new NullPointerException("onNext called with null. Null values are generally not allowed in 2.x operators and sources."));
return;
}
/ 若无断开连接(调用Disposable.dispose()),则调用观察者(Observer)的同名方法 = onNext()
// 观察者的onNext()的内容 = 使用步骤2中复写内容
if (!isDisposed()) {
observer.onNext(t);
}
}
// onError()、onComplete()类似
// 特别说明:调用这两个方法,最终都会自动调用dispose(),即断开观察者 & 被观察者的连接,看finally
@Override
public void onError(Throwable t) {
if (!tryOnError(t)) {
RxJavaPlugins.onError(t);
}
}
@Override
public boolean tryOnError(Throwable t) {
if (t == null) {
t = new NullPointerException("onError called with null. Null values are generally not allowed in 2.x operators and sources.");
}
if (!isDisposed()) {
try {
observer.onError(t);
} finally {
dispose();
}
return true;
}
return false;
}
@Override
public void onComplete() {
if (!isDisposed()) {
try {
observer.onComplete();
} finally {
dispose();
}
}
}
}
2、Observer
观察者 & 定义响应事件的行为
看源码得知Observer是个接口,包含如下方法:
public interface Observer<T> {
// 接口内含4个方法,分别用于 响应 对应于被观察者发送的不同事件
void onSubscribe(@NonNull Disposable d);
void onNext(@NonNull T t);
void onError(@NonNull Throwable e);
void onComplete();
}
3、subscribe
通过订阅(subscribe)连接观察者和被观察者
源码分析:Observable.subscribe(observer)
/**
* 源码分析:Observable.subscribe(observer)
* 说明:该方法属于 Observable 类的方法(注:传入1个 Observer 对象)
**/
@Override
public final void subscribe(Observer<? super T> observer) {
...
// 贴出关键源码
subscribeActual(observer);
// 继续往下分析
}
/**
* Observable.subscribeActual(observer)
* 说明:属于抽象方法,由子类实现;此处的子类 = 步骤1创建被观察者(Observable)时创建的ObservableCreate类
* 即 在订阅时,实际上是调用了使用步骤1中创建被观察者(Observable)时创建的ObservableCreate类里的subscribeActual()
*
**/
protected abstract void subscribeActual(Observer<? super T> observer);
4、总结
Rxjava的流程是:
1、Observable.create 创建事件源,但并不生产也不发射事件。
2、实现observer接口,但此时没有也无法接受到任何发射来的事件。
3、订阅 observable.subscribe(observer), 此时会调用具体Observable的实现类中的subscribeActual方法, 此时会才会真正触发事件源生产事件,事件源生产出来的事件通过Emitter的onNext,onError,onComplete发射给observer对应的方法由下游observer消费掉。从而完成整个事件流的处理。