RxJava 初探(网络请求)

来源:互联网 发布:淘宝企业店铺交税问题 编辑:程序博客网 时间:2024/06/02 00:10

RxJava 介绍


写在前面

rxjava 也用了好多次了。时隔多年,才终于有勇气挖一下它的源码。
这次主要研究了发布订阅流程 subscribe() 以及核心变换 lift(),至于其他的像线程切换 Schedulers、丰富的操作符啊,都有待研究。
之后可能会再更新几篇,也可能就太监了。。。
1.RxJava 源码分析之 —— lift 变换


What is RxJava?

RxJava 的思想是响应式编程,这是一种事件驱动的编程模式。事件驱动很熟悉吧,经典如通过 Listener 来监听点击事件再回调 OnClick(),这种方式早就烂大街了吧。RxJava 本质上与这种监听器没有区别,那么它又有什么独到之处呢?


Why RxJava?

它的独到之处在与它响应式的编程思想——一切皆抽象为事件。如果说对于点击事件,Android 本身已经提供了一套监听方案,那么网络请求呢,文件读写呢,还有数不清的事件呢。。此前,我们都是自己编写网络请求框架,然后对外提供回调接口 OnSuccess() 、OnFail()。换成文件读写,又得重新搞一套框架,我们累了,需要一个通用的解决方案,它就是 RxJava 。
By the way,解决了”回调地狱”只是顺带的好处罢了。


Where RxJava?

那么什么场景下使用它呢?
它的应用场合很多,本文将以网络请求为例做一个 Demo。

更多场景请参考这篇文章:
可能是东半球最全的RxJava使用场景小结


How RxJava?

要使用 RxJava 还得深入到代码层面。
它是基于观察者模式实现的,那么自然会有一个被观察者(可观察的对象) Observable 和 一个观察者(订阅者)Subscriber。


需要的第三方包

// app/build.gradledependencies {    // 。。。    // rxjava    compile 'io.reactivex:rxjava:1.0.14'    compile 'io.reactivex:rxandroid:1.1.0'    // rxlifecycle    compile 'com.trello:rxlifecycle:0.4.0'    compile 'com.trello:rxlifecycle-components:0.4.0'    // 上面4个包是必要的    // okhttp    compile 'com.squareup.okhttp:okhttp:2.7.2'    // butterknife     compile 'com.jakewharton:butterknife:7.0.1'}

最好配合上 retrolambda 这个插件,用 lambda 语法写起来才爽。

概念介绍

先来看一下 Subscriber 包含了哪些东西

// 打开源码我们看到 Subsctiber 实现了 Observerpublic abstract class Subscriber<T> implements Observer<T>, Subscription { ... }// 而 Observer 包含有一些回调函数// {OnNext(), OnError(), OnComplete()}public interface Observer<T> {    void onNext(T t);    void onError(Throwable e);    void onCompleted();}

然后看看它怎么订阅事件

// Subscriber 作为监听器,需要注册到 Observable 中:// (我们才能在 Observable 中回调它的一些函数)mObservable.subscribe(mSubscriber);// 这类似于我们注册点击事件的监听:mView.setOnClickListener(mOnClickListener);// 可以对应起来理解,View 即是被观察者,// 而 OnClickListener 则是订阅者。

其中,mSubscriber 是这样的

// 当然,正如 mOnClickListener 实现了 OnClick(),// mSubscriber 作为匿名类实现了三个接口函数,像这样:Subscriber<String> mSubscriber = new Subscriber<String>() {      @Override      public void onNext(String s) { }      @Override      public void onCompleted() { }      @Override      public void onError(Throwable e) { }  };  

一些简化写法:

// 考虑到这样的匿名类写法比较冗长,而且不能用 lambda 简化,// 作者还提供了 subscribe(mSubscriber) 的一些重载版本:mObservable.subscribe(onNext);mObservable.subscribe(onNext, onError);mObservable.subscribe(onNext, onError, onComplete);// 太棒了,它们都是函数式接口,可以用 lambda 简化代码。


再来看一下 Observable , 之前说到它可以被 Subcriber 订阅。但是在此之前,我们需要先创建它。

// 创建 Observable 实例mObservable.create(mOnSubscribe); // 其中 mOnSubscribe 接口,用来制定事件分发的流程。// 即按照一定顺序,回调之前注册好的三个函数: // {OnNext(), OnError(), OnComplete()}Observable.OnSubscribe<String> mOnSubscribe = new Observable.OnSubscribe<String>() {    @Override    public void call(Subscriber<? super String> subscriber) {        String data = getData(); // 获取数据: 网络任务或是别的...        if(data == null){ // 获取失败            subscriber.onError(new Throwable("data 为空"));            subscriber.onCompleted();        }else{ // 获取成功            subscriber.onNext(data);            subscriber.onCompleted();        }    }};

What’s more,Observable 还可以分别指定 Observable 和 Subcriber 的线程:

Observable.create(subscriber -> {})    .subscribeOn(Schedulers.io()) // 指定 Observable 的线程 ———— 主线程。    .observeOn(AndroidSchedulers.mainThread()); // 指定 Subscriber 的线程 ———— io 线程。

框架内部估计封装了线程切换的功能,这在 Android 的多线程环境中,极大地简化了线程操作。

实践

我们来试一下网络请求吧,从网上拉取一段字符串(http://publicobject.com/helloworld.txt)。首先,我们把一个请求看作一个事件,先创建一个事件对应的被观察者 NetworkObserable.getInstance() : Observable< String >。

public class NetworkObserable{    ...    // 获取一个 Observable 实例    public static Observable<String> getInstance() {        return Observable.create((Observable.OnSubscribe<String>)                subscriber -> subscribeData(subscriber, NetworkHelper.getData(NetworkHelper.GET))                // getData()发起一个GET请求,返回 String 数据。            ).subscribeOn(Schedulers.io());              // 被观察的对象在 io 线程进行网络请求,也可以自己新开一个线程    }    // 取得网络数据后,回调 subscriber 的一些函数,在界面上显示这些数据    private static void subscribeData(Subscriber<? super String> subscriber, String data){        if(data == null){            subscriber.onError(new Throwable("data 为空"));            subscriber.onCompleted();        }else{            subscriber.onNext(data);            subscriber.onCompleted();        }    }}

在点击按钮的时候订阅这个事件。

@OnClick(R.id.btn_GET) public void onClick() {    NetworkObservable.getInstance()                 // 获取 Observable 实例        .compose(this.<String>bindToLifecycle())    // Rxlifecycle, 绑定到 Activity 的生命周期。        .observeOn(AndroidSchedulers.mainThread())  // 指定观察者的线程————主线程。        .subscribe(                                 // 订阅事件            // onNext, 请求成功            data -> mTvResult.setText(data),            // onError, 请求失败            throwable -> Toast.makeText(this, throwable.getMessage(), Toast.LENGTH_SHORT).show()        );}

然后,没有然后了。。。


附录

按照惯例,放上 Demo 地址,有兴趣可以下载一下:
https://github.com/fashare2015/my_rxjava_demo

1 0
原创粉丝点击