写给Rikka自己的RxJava2说明书

我们先建立一个Retrofit对象,并且让他添加RxJava和Gson的适配工厂

String url = “https://www.bilibili.com/”;

Gson gson = new Gson();

Retrofit retrofit = new Retrofit.Builder()

.baseUrl(url)

//添加RxJava2的适配

.addCallAdapterFactory(RxJava2CallAdapterFactory.create())

//添加Gson的转换

.addConverterFactory(GsonConverterFactory.create(gson))

.build();

然后创建Api 的对象并且实现Api的方法:

Api api = retrofit.create(Api.class);

api.getSearchDefault()

//将网络请求放在后台

.subscribeOn(Schedulers.io())

//将结果的返回放在前台

.observeOn(AndroidSchedulers.mainThread())

.subscribe(new SingleObserver<List>() {

@Override

public void onSubscribe(Disposable d) {

Log.d(TAG, “onSubscribe”);

}

@Override

public void onSuccess(List repo) {

Log.d(TAG, repo.get(0).toString());

}

@Override

public void onError(Throwable e) {

Log.e(TAG, e.getMessage());

}

});

其中

.subscribeOn(Schedulers.io())

.observeOn(AndroidSchedulers.mainThread())

这两个后面在解析,是有关于线程调度的,而且一定要加这两行,不让Retrofit是不会把网络请求放在后台的…那样的话网络请求可能会阻塞,一定会报错。

// subscirbe == enqueue

.subscribe(new SingleObserver<List>() {

});

至于上面这个 subscribe方法其实就相当于Okhttp的 enqueue方法,让这个网络去执行!

然后参数就是网络的回调,有 onSubscribeonSuccessonError方法,分别代表执行、网络请求成功并返回结果,网络请求失败。我们在success中打印结果。

接下来我们来运行程序,得到下面的结果:

在这里插入图片描述

Ok,看来请求成功辽。

从上面的图中可以分析一下:从onSubsrcibe到onSuccess,用了1s多的时间,这就是一个网络请求的时间。那么onSubscribe就是程序一开始执行所会回调的程序。

那我们就来仔细的去了解其中的几个方法,首先最开始的Single的介绍开始

Single是啥?有什么用


为了更好的介绍Single,我们可以来写一下Single的一个简单的示例:

Single single = Single.just(“1”);

single.subscribe(new SingleObserver() {

@Override

public void onSubscribe(Disposable d) {

}

@Override

public void onSuccess(String s) {

Log.d(TAG, s);

}

@Override

public void onError(Throwable e) {

}

});

在这里,我们要引入 订阅者观察者 两个概念:

  • 订阅者/被观察者

就是接收消息的一方,订阅事件的一端,在有事件传过来的时候,可以得到这些事件。然后可以对事件进行处理。

在本例中,订阅者就是subscribe() 括号里面的东西,就是那个 SingleObserver 对象

它所做的三个方法 ,就是对 发送方发送的 Disaponable、String、Throwable进行处理。

  • 观察者

就是发送消息的一方,发送事件的一端,当执行完任务后,会得到一份结果,但自己不能处理,只能给订阅者处理,自己看着他处理(我自己烤了个鸡腿,但是我只能递给你,眼巴巴的看着你吃QAQ)

所以这也是为什么:发送事件的一方叫做观察者,接收事件的一方又叫做被观察者

在本例中,观察者就是Single single,它使用just()方法向 被观察者 发送了一个字符 “1”,然后使用了subscribe()方法来观察 被观察者 怎么处理这个“1”。

构造一个Single,这个just(“1”) 就是指订阅者在订阅的一瞬间,发送者就会给接收者发送一个 “1”。

程序的输出的确就是1没错。

我们接下来来分析一下just() 是具体干了什么,从源码的角度分析。(这里开始刚源码啦)

just()源码


我们来追踪一下just()的源码:

@CheckReturnValue

@SchedulerSupport(SchedulerSupport.NONE)

public static Single just(final T item) {

//这一行是判空操作

ObjectHelper.requireNonNull(item, “value is null”);

return RxJavaPlugins.onAssembly(new SingleJust(item));

}

那个return句子有两个东西, 一个是 onAssembly()的东西,另一个是它传入的SingleJust对象,,Assembly就是集合的意思,这说明它会对括号里的参数进行一个“装箱”。我们来看看onAssembly()方法:

@NonNull

public static Single onAssembly(@NonNull Single source) {

//Fuction是一个转换器,把传入的对象 转换成一个 要处理的 传出的对象

//onSingleAssembly是一个转换后的结果…我们一般用不上这个参数

Function<? super Single, ? extends Single> f = onSingleAssembly;

if (f != null) {

return apply(f, source);

}

return source;

}

这句话就是把传入的对象进行一个加工处理。

然后就出来了,也就是说,return语句的关键在于另一条SingleJust这个对象。

我们打开了SingleJust的类,把焦点聚集在下面这个方法上

//SingleJsust 重写了下面方法

@Override

protected void subscribeActual(SingleObserver<? super T> s) {

//woc!这不就是外面 subscribe调用的方法咩?它们绝壁有关联的

s.onSubscribe(Disposables.disposed());

s.onSuccess(value);

}

可以这么说,Single通过just() 方法创建了一个SingleJust的对象。

然后SingleJust里面有 subscribeActual() 方法,它会调用参数的onSubscribe()和onSuccess()方法,而这就和Single调用的subscribe()方法一样,有一个大胆的猜测就是我们调用 Single的 subscribe() 其实就是调用 SingleJust的 subscribeActual()方法。

抱着这个猜测,我们去查看subscrible()的源码:

在这里插入图片描述

第一、二、三行分别是判空和包装,不看!

try/catch只看try语句,所以到最后,它就是调用了 subscribeActual()这个方法!

那么在这里就可以总结下了:

  • Single通过just()来构造了一个对象,这个对象使用subscrible()方法的执行其实就使用了SingleJust的 subscribeActual()方法。他直接调用了onSubscribe啊onSuccess!

  • 所以我们 重写了 subscribe(),等于我们定制了 subscribleActual()方法

这就是 subscrible()的作用,它会直接调用我们重写的SingObserver的东西。

所以 当我们在网络请求搞完了,retrofit得到了一个response之后,我门就是拿着它去走 subscrible()方法的回调的~

接下来,我们先不讲解线程调度,也不讲回调方法,我们来看一下RxJava一个特有的东西:操作符

map操作符


map()方法的作用是:转换数据类型

比如说我得到的网络申请结果是一个Integer,但是我要发给 订阅者 的是String,那么我在每次发送之前就要把Integer转换成String,就要在map()里面做:

Single single = Single.just(1);

single.map(new Function<Integer, String>() {

@Override

public String apply(Integer integer) throws Exception {

return String.valueOf(integer);

}

});

我们传入了一个1,然后在使用map()去构造Function然后重写了apply方法,最后在apply方法中,我们就是做类型的装换哒。

以上就是map操作符的用法,看起来是不是比较简单呢?但是如果你想深入一点研究这个map,会发现它还是有点用法的规矩的。

首先map在链式构造里面不等于建造模式,因为它不是返回this,比如:

single.map(new Function<Integer, String>() {

}).subscribe(new SingleObserver() {

});

这是因为使用map后返回的对象已经不同了= =。我们来看看map()方法:

在这里插入图片描述

是通过传入的function来转换成一个 SingleMap对象。

然后返回的值和之前的 SingleJust都不同啦!结构都变了…后面如果使用了subscrible(),那调用的就不是SingleJust的subscribeActual()了,而是调用SingleMap()的subscribeActual()了,而这个方法的具体实现如下:

@Override

protected void subscribeActual(final SingleObserver<? super R> t) {

//帮SingleObserver去做网络请求了,所以map在中间相当于做了一个代理

source.subscribe(new MapSingleObserver<T, R>(t, mapper));

}

实际上,SingleMapsubscribeActual()方法里面会创建一个MapSingleObserver,来调用Observer的那三个方法:

在这里插入图片描述

有两个参数:

  • SingleObserver t

我们自己重写的SingleObserver(),里面有我们自己定制的onSuccess()、onSubscribe()、onError()

  • Funcation mapper

这个是我们在map中重写的 apply()方法

在往下面看,发现MapSingleObserver也会走那三个方法,而更重要的是在 onSuccess()方法中对结果 value值进行了apply()的处理,然后返回这个结果。

到这里我们就大概知道map所做的事情了,我们可以用下面几幅图来描述一下map所做的事情:

①:当没有使用map的时候,就是调用SingleJust的subscribe()方法。

在这里插入图片描述

②:当我们使用了map操作符后

在这里插入图片描述

map就是做了个代理,我们使用了map的subscribeActual(),它会帮我们去做后台请求,又能把结果转换目标类型,这样看的话其实很简单。

了解了map这个操作符,我们就来了解一下 Disponsable这个对象,但是由于它出现在onSubscribe()里面,所以我们先看一下onSubscribe()这个方法是干什么的吧~

onSubscribe(Disponsable disposable)


我们在 onSubscribe(Disponsable disposable) 看到里面有个参数:Disponsable

它是做什么的呢?

用来取消订阅

Rxjava可以让订阅者和被订阅者断开,之后的内容不再发送;发消息的人也可以停下来。

可以通过调用Dispinsable的方法来取消后续的发送。比如:

@Override

public void onSubscribe(Disposable d) {

d.dispose();

Log.d(TAG, “onSubscribe”);

}

那它在执行完onSubscribe后,就不会再走 onSuccess() 或者 onError方法了。

那么Disponsable用途是干嘛的捏?

一般是用来防止内存、流量泄露。比如我(被观察者)已经拿完了并且处理完应该要做完的事件,但是这个时候观察者还在后台的不断的申请资源和发送事件,那一到我这个主线程来也会进入onSuccess()方法,我是不知道的,所以会多出很多不必要的东西来占用内存。

so,通过disposable来断开观察者和被观察者的连接。

Ok,Disposable的用处讲完了,那么我们就来从源码的角度分析Disposable吧。

Disposable


首先不同的Observerable,它们的Disponsable都不一样,因为要做的切断的具体操作是不一样。

它就是切断观察者和被观察者的联系。

它是一个接口:

public interface Disposable {

void dispose();

boolean isDisposed();

}

这两个方法都特别好理解。用在最上层的Observerable 就实现dispose()了。

它在走onNext()会判断当前自己的disposable()里面的机制会不会让自己停止,如果是的话,那就不会再走onNext()了。

Dispose会从上一直往下传,每一层如果停掉了当前了Disponse,那它也会停掉了上一层的传递。就是这样。

subscribeOn


subscribeOn也是一个操作符,但它操作的不是数据,而是线程。它把数据、请求放到了后台线程去。

所以我们还是要去看它的subscribeActual()做了什么。

@Override

protected void subscribeActual(final SingleObserver<? super T> s) {

final SubscribeOnObserver parent = new SubscribeOnObserver(s, source);

s.onSubscribe(parent);

//通过schedule做线程切换

Disposable f = scheduler.scheduleDirect(parent);

parent.task.replace(f);

}

parent是最上层的Observer,并把它包装成了一个Runnable对象。而它重写了run方法就是:

@Override

public void run() {

//把请求网上调了

source.subscribe(this);

}

就相当于:

在这里插入图片描述

scheduler还是使用了Executor去进行线程切换,而不直接使用Executor的原因是scheduler的场景在RxJava2更多。

从图中也可以看出,如果多次使用subscribeOn(),则最上层(即第一行)的subscribeOn()才会起作用

Disposable f = scheduler.scheduleDirect(parent) 中的f作为Dsponsable可以被我所控制,如果我们在外边调用了dispose(),则里面也会调用这个f的dispose()。

至于切线程的具体细节,这里就不多讲了。

ObserverOn


研究它和研究SubscribeOn()一样,也是看subscribeActual():

@Override

protected void subscribeActual(final SingleObserver<? super T> s) {

source.subscribe(new ObserveOnSingleObserver(s, scheduler));

}

它直接就把数据交往上层了,在数据的过去时没做任何操作:

在这里插入图片描述

所以它真正做的事情不在subscribeActual()里面。

因为ObserverOn是掌管数据回来的线程,所以用脚都能想到,它的处理,肯定是在数据回来,也就是Obseverable的onSuccess和onError()中:

@Override

public void onSuccess(T value) {

this.value = value;

//scheduleDirect切换线程

Disposable d = scheduler.scheduleDirect(this);

DisposableHelper.replace(this, d);

}

@Override

public void onError(Throwable e) {

this.error = e;

//scheduleDirect切换线程

Disposable d = scheduler.scheduleDirect(this);

DisposableHelper.replace(this, d);

}

@Override

public void run() {

Throwable ex = error;

if (ex != null) {

actual.onError(ex);

} else {

actual.onSuccess(value);

}

}

最后

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级Android工程师,想要提升技能,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助

因此我收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点!不论你是刚入门Android开发的新手,还是希望在技术上不断提升的资深开发者,这些资料都将为你打开新的学习之门

如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
or;

if (ex != null) {

actual.onError(ex);

} else {

actual.onSuccess(value);

}

}

最后

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级Android工程师,想要提升技能,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助

因此我收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

[外链图片转存中…(img-5fLbhwmH-1715884985685)]

[外链图片转存中…(img-qWspId16-1715884985687)]

[外链图片转存中…(img-o28OO6WY-1715884985689)]

[外链图片转存中…(img-jdANs7c2-1715884985691)]

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点!不论你是刚入门Android开发的新手,还是希望在技术上不断提升的资深开发者,这些资料都将为你打开新的学习之门

如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值