Android RxJava 学习笔记1

RxJava


RxJava RxAndroid

RxJava in Android 最近很流行,感觉很有必要掌握以下,这里主要当作一个学习笔记.

文中夹杂一些英文主要是打字方便 不是ZB 请见谅。

0 阅读之前

有很多写得很好的教程 我要提前post在这里: 强烈推荐扔物线的一篇教程 《给 Android 开发者的 RxJava 详解》。

1 为什么需要 RxJava

1.1 Android Basics

Android Process and Thread

请重点参考官方文档:《Android进程和线程》。 当一个Android App启动的时候,因为是基于linux的所以其实上回起一个linux进程然后其中有一个线程在跑 默认情况下, 所有这个app的component(service, activity, etc.)都跑在同一个进程和线程(这个线程叫做主线程)。 当然你可以选择让这些component跑在新的不同的进程并且你可以为任意进程添加线程。

BTW 这个主线程也就是我们常说的UI线程, 它会handle很多和UI相关的event 负责更新UI和android ui tookit交互,通常我们为了保持Android app的 responsiveness 开发者需要避免在这个线程上做太多和UI不相干的task,而将这些task跑在separate threads (“background” or “worker” threads) Android 提供了runOnUiThread 来让你在sepearate threads中来access main UI thread。

Android Async

正如其所说的, 在Android里面有很多异步编程, 比如你点一个按钮,触发一个thread,或者 网络请求中, 等待返回。通常我们要把这些任务放到worker thread上来异步执行从而避免阻塞UI thread。 请阅读这里 《Android异步处理系列文章索引

现有的常用Android Async编程模式有

Handler

前文提到可以new thread然后在来和UI thread交互通行但是如果你的worker thread多了业务逻辑复杂就会很麻烦。 android 提供了handler 来简化线程间的消息传递和处理

AsyncTask

这个是目前android主推的异步编程模式 直接quote了

The method doInBackground() executes automatically on a worker thread onPreExecute(), onPostExecute(), and onProgressUpdate() are all invoked on the UI thread

对于Handler和AsyncTask的 Taste, 请阅读 《ASYNCHRONOUS ANDROID PROGRAMMING THE GOOD, THE BAD, AND THE UGLY》 Android的工程师想通过handler和asynctask来简化异步编程 但是这里面都有难以避免的问题 比如:容易内存泄漏,无法保证task完成的顺序, 复杂的逻辑不好实现, 出现错误不容易终止 等等。

1.2 RxJava 简介

观察者模式

也叫PubSub 这里 给了图示和例子。 一句话:

An Observer subscribes to an Observable

Subscriber

观察者

RxJava 里 提供了 Observer接口 和 Subscriber抽象类 两者用法是一致的。

不仅基本使用方式一样,实质上,在 RxJava 的 subscribe 过程中,Observer 也总是会先被转换成一个 Subscriber 再使用。所以如果你只想使用基本功能,选择 Observer 和 Subscriber 是完全一样的。 —–from 给 Android 开发者的 RxJava 详解

两者都有如下方法 onNext, onCompleted, onError

这里是Observer接口的三个需要实现的回调方法,对应三种事件

  • onCompleted 通知 observer: observable 已经结束了send push-based notifications.
  • onError 通知 observer: observable 出错了
  • onNext 让 observer observe一个新的 item

前面两种是特殊事件 表示完结和出错 后面一个是普通事件 onCompleted 和 onError 互斥,即一个 Subscriber 对于一个 observable 只可能看到 completed 或者 error,且一旦看到 completed 或者 error 就不会再有新的普通事件,也就是说 onCompleted 和 onError 一定是一个队列中最后一个事件

Subscriber 还有 onStart 方法 和 unsubscribe 方法。 前者用来在事件发送之前做准备工作 后者则是取消订阅

Observable

被观察者

创建Observable的方法很多 最基本是 create

public final static <T> Observable<T> create(OnSubscribe<T> f) {
    return new Observable<T>(hook.onCreate(f));
}    

一个实现了OnSubscribe接口的对象被当作输入参数

OnSubscribe 会被存储在返回的 Observable 对象中,它的作用相当于一个计划表,当 Observable 被订阅的时候,OnSubscribe 的 call() 方法会自动被调用,事件序列就会依照设定依次触发。这样,由被观察者调用了观察者的回调方法,就实现了由被观察者向观察者的事件传递,即观察者模式。 —–from 给 Android 开发者的 RxJava 详解

除了create还有 from just 等创建observable的方法

Subscribe

observable.subscribe(observer);
// or
observable.subscribe(subscriber);

return 的是一个 Subscription类 这里的 subscribe 是反过来的, 其实是

An Observer subscribes to an Observable —-> An Observable notifies an Observer

这样处理的结果是编程代码的易读

不完整定义的回调 Action*

Action0 Action1 Action2 etc. 分别接受不同数目的输入参数 然后 一般用 Action0 和 Action1

// 用了 《给 Android 开发者的 RxJava 详解》 里的例子
Action1<String> onNextAction = new Action1<String>() {
    // onNext()
    @Override
    public void call(String s) {
        Log.d(tag, s);
    }
};
Action1<Throwable> onErrorAction = new Action1<Throwable>() {
    // onError()
    @Override
    public void call(Throwable throwable) {
        // Error handling
    }
};
Action0 onCompletedAction = new Action0() {
    // onCompleted()
    @Override
    public void call() {
        Log.d(tag, "completed");
    }
};
// 自动创建 Subscriber
// onNextAction, onErrorAction, onCompletedAction
observable.subscribe(onNextAction);
observable.subscribe(onNextAction, onErrorAction);
observable.subscribe(onNextAction, onErrorAction, onCompletedAction);

给了用户很大的灵活性来创建 Subscriber

来看看 Action1 接口

public interface Action1<T> extends Action {
    void call(T t);
}

Scheduler

还是读 《给 Android 开发者的 RxJava 详解》吧。

  • Schedulers.immediate() 同一线程
  • Schedulers.newThread() 总是启用新thread
  • Schedulers.io() IO 操作(读写文件、读写数据库、网络信息交互等,无数量上限的线程池
  • Schedulers.computation() 固定的线程池,大小为 CPU 核数

scheduling 方法

  • subscribeOn() 事件发出的线程, subscribe() 所发生的线程
  • observeOn() 事件消费 Subscriber 的回调发生的线程

RxAndroid

它提供了一个可以在给定的Android Handler 上调度 Observable 的调度器 Scheduler,特别是在UI主线程上

  • AndroidSchedulers.handlerThread(handler)
  • AndroidSchedulers.mainThread()

1.3 RxJava 优点

在使用这样一种编程模式, 能够带来的最大好处就是代码的简洁明了 可维护性高 最大程度的规避 回调地狱

请对比 这里的两个例子: 一个是用 Android 本身的 thread + runOnUiThread 另一个是用的 RxJava 明显可以感觉到 使用 RxJava 的代码可读性高 逻辑清晰 这对于软件工程来说非常的关键。 可能一个小proj无所谓,但是对于复杂的app RxJava带来的优点非常关键。

这是学习笔记第一篇 日后会补充更多的代码例子 和 更多好的references

Reference