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
- RxJava 初探(网络请求)
- Android网络请求(二)retrofit+rxjava
- RXJava+Retrofit网络请求
- Okhttp网络请求+Rxjava
- RxJava 初探(一)
- RxJava+retrofit2实现网络请求
- RxJava + Retrofit完成网络请求
- callback网络请求转RxJava
- Rxjava+Retrofit取消网络请求
- Retrofit+RxJava处理网络请求
- RxJava + Retrofit完成网络请求
- Retrofit+RxJava网络请求框架
- Retrofit+Rxjava完成网络请求
- RXjava加okhttp 请求请求网络数据
- RxJava+Retrofit+OkHttp深入浅出-终极封装二(网络请求)
- RxJava+Retrofit+OkHttp深入浅出-终极封装二(网络请求)
- RxJava+Retrofit+OkHttp深入浅出-终极封装二(网络请求)
- RxJava+Retrofit+OkHttp深入浅出-终极封装二(网络请求)
- 第K短路
- Visual EmbedLinux Tools 0.2.6
- NetworkUtils 网络相关的工具类NetworkUtils
- cookie 和session 的区别详解
- <Sicily>Fibonacci 2
- RxJava 初探(网络请求)
- 三流学校毕业生的程序学习之路
- django中在主项目urls.py中调用app中的urls.py
- Nginx的命令行控制
- niuniu
- 胡润研究院第二年发布中国豪华车品牌特性研究白皮书
- Java 多线程 并发编程
- set
- Spring bean的生命周期