先看下别人实现的最基本的RxJava的实现方式:

在RxJava里面,有两个必不可少的角色:Subscriber(观察者) 和 Observable(订阅源)。

Subscriber(观察者)

Subsribler在RxJava里面是一个抽象类,它实现了Observer接口。

public interface Observer<T> {
void onCompleted();
void onError(Throwable t);
void onNext(T var1);
}

为了尽可能的简单,将Subscriber简化如下:

public abstract class Subscriber<T> implements Observer<T> {
public void onStart() {
}
}

Observable(订阅源)

Observable(订阅源)在RxJava里面是一个大而杂的类,拥有很多工厂方法和各式各样的操作符。每个Observable里面有一个OnSubscribe对象,只有一个方法(void call(Subscriber<? super T> subscriber);),用来产生数据流,这是典型的命令模式

public class Observable<T> {
final OnSubscribe<T> onSubscribe; private Observable(OnSubscribe<T> onSubscribe) {
this.onSubscribe = onSubscribe;
} public static <T> Observable<T> create(OnSubscribe<T> onSubscribe) {
return new Observable<T>(onSubscribe);
} public void subscribe(Subscriber<? super T> subscriber) {
subscriber.onStart();
onSubscribe.call(subscriber);
} public interface OnSubscribe<T> {
void call(Subscriber<? super T> subscriber);
}
}

实践

到此,一个小型的RxJava的雏形就出来了。不信?我们来实践一下吧。

 Observable.create(new Observable.OnSubscribe<Integer>() {
@Override
public void call(Subscriber<? super Integer> subscriber) {
for (int i = 0; i < 10; i++) {
subscriber.onNext(i);
}
}
}).subscribe(new Subscriber<Integer>() {
@Override
public void onCompleted() { }
@Override
public void onError(Throwable t) { }
@Override
public void onNext(Integer var1) {
System.out.println(var1);
}
});

OK,先来消化下最基本的知识:

首先Observable(订阅源)内部有个接口 OnSubscribe ,其中有个 call 方法。

其次Observable(订阅源)内部持有  final OnSubscribe<T> onSubscribe; 属性,但没有实例化,它在什么地方实例化呢,在 create 方法中,实例下这个 onSubscribe 属性,并且需要实现 call 方法。

接着Observable(订阅源)执行 subscribe 触发事件,其中  onSubscribe.call(subscriber); 则回调执行实例化的 onSubscribe 且实现的 call 方法。

对比下Android的OnClickListener的实现

    Button.setOnClickListener(new OnClickListener(){
@Override
public void onClick(View v) {
// do something
}
});
Button相当于Observable;---> 被监听的对象
OnClickListener相当于OnSubscribe;---> 接口
onClick相当于call;---> 接口回调方法

当我们点击按钮的时候,点击的事件系统分发到Button上,类似subscribe,回调执行onClick方法,通常情况下,我们对onClick(View v)中的View不感兴趣,但其实,这个View就是Button,我们可以对其进行操作。
        button = (Button) findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Log.d(TAG, "view instanceof Button:" + (view instanceof Button));
Log.d(TAG, "view == button:" + (view == button));
view.setVisibility(View.GONE);
}
});

所以在使用上可以简单的理解为:

输入的数据 ---> 被监听者(订阅源)对这些数据进行操作,或者执行响应的处理 --> 产生新的数据,或者事件发送给监听者 --> 监听者执行自己的方法。

        Observable.create(new Observable.OnSubscribe<String>() {

            @Override
public void call(Subscriber<? super String> subscriber) {
subscriber.onNext("hello rxjava");
}
}).subscribe(new Action1<String>() {
@Override
public void call(String s) {
Log.d(TAG, s);
}
});

参考资料:

一起来造一个RxJava,揭秘RxJava的实现原理

给 Android 开发者的 RxJava 详解

RxJava 1.x 理解-1的更多相关文章

  1. RxJava 2.x 理解-3

    背压:Flowable / Subscriber 在RxJava 1.x 理解 中,没有讲到背压这个概念,是因为学习太落后了,RxJava都出2了,所以直接在2上学. 背压是下游控制上游流速的一种手段 ...

  2. RxJava 2.x 理解-1

    在RxJava 1.x 系列中,讲解了RxJava的大致用法,因为现在都用RxJava 2了,所以Rxjava 1就不细讲,主要来学习RxJava 2. 基本使用: /** * rajava2 的基本 ...

  3. RxJava 1.x 理解-3

    在 RxJava 1.x 理解-1 中,我们说到了RxJava的简单用法,但是这还远远不够,因为 输入的数据 ---> 被监听者(订阅源)对这些数据进行操作,或者执行响应的处理 --> 产 ...

  4. RxJava 1.x 理解-2

    给RxJava 加入线程控制 -- Scheduler 在 RxJava 1.x 理解-1 中,我们说到了RxJava的简单用法,但是这还远远不够,因为这简单用法是在同一个线程中使用的.比如我们需要在 ...

  5. RxJava 2.x 理解-2

    操作符总结: http://reactivex.io/documentation/operators.html https://github.com/ReactiveX/RxJava/wiki Ope ...

  6. RxJava+RxAndroid+MVP入坑实践(基础篇)

    转载请注明出处:http://www.blog.csdn.net/zhyxuexijava/article/details/51597230.com 前段时间看了MVP架构和RxJava,最近也在重构 ...

  7. 如何深入理解Java泛型

    一.泛型的作用与定义 1.1泛型的作用 使用泛型能写出更加灵活通用的代码泛型的设计主要参照了C++的模板,旨在能让人写出更加通用化,更加灵活的代码.模板/泛型代码,就好像做雕塑时的模板,有了模板,需要 ...

  8. 必读的 Android 文章

    必读的 Android 文章 掘金官方 关注 2017.06.07 13:58* 字数 25218 阅读 8782评论 2喜欢 218 写给 Android 开发者的混淆使用手册 - Android ...

  9. Android 使用Retrofit2.0+OkHttp3.0实现缓存处理+Cookie持久化第三方库

    1.Retrofit+OkHttp的缓存机制 1.1.第一点 在响应请求之后在 data/data/<包名>/cache 下建立一个response 文件夹,保存缓存数据. 1.2.第二点 ...

随机推荐

  1. 一个IT中专生在深圳的9年辛酸经历

    一个IT中专生在深圳的9年辛酸经历 想一想来到深圳已经近10年了,感概万千呐!从一个身无分文的中专职校计算机毕业出来后,竟然大胆的南下(之前可是连我们那地区之外都没去过),现在有供完的房子,温柔的妻子 ...

  2. 使用apache构建OpenStack内部yum源

    安装apache yum install httpd -y 上传openstack-mitaka-rpms.tar包,链接:http://pan.baidu.com/s/1kVA1wKv 密码:q26 ...

  3. 如何使主机和虚拟机IP处于同一网段(内网渗透专用)

    先说一下正常流程: 1.打开虚拟机网络设置选项,选择桥接模式(Bridged)[如果是Kali 2.0的话,执行第一步后就OK了(90%)] 2.打开Kali里面的网络设置 3.设置一个ip4或者ip ...

  4. BZOJ 100题纪念

  5. Python小程序之动态修改Haproxy配置文件

    需求如下: 1.动态的查询添加删除haproxy节点信息 2.程序功能:add(添加).Del(删除).Query(查询) 3.添加时实例字符串为:  {'backend': 'www.oldboy. ...

  6. linux下rm命令删除文件名中包含特殊字符的文件【转】

    转自:http://blog.itpub.net/143526/viewspace-1060083/ 1. 删除带“-”的文件名的方法 2. 删除包含其它特殊字符的文件 3. 删除系统打不出的乱码文件 ...

  7. Oracle基础 04 归档日志 archivelog

    --查看归档模式archive log list select log_mode from v$database; --修改为归档模式(mount下)alter database archivelog ...

  8. UI变化之动画效果

    很多时候我们在需要动态的改变某一个场景下的显示. 最常见的一个场景就是view的最大化. 我们直接设置view的frame可以实现最大化,但是这样的最大化是突变的没有动画效果. 苹果可以将这种突变“放 ...

  9. 【 sysbench 性能基准测试 】

    度娘解释:sysbench是一款开源的多线程性能测试工具,可以执行CPU/内存/线程/IO/数据库等方面的性能测试. 目前支持的数据库支持:MySQL,pgsql,oracle 这3种数据库. 安装s ...

  10. docker从零开始 存储(六)存储驱动如何选择

    Docker存储驱动程序 理想情况下,将非常少的数据写入容器的可写层,并使用Docker卷来写入数据.但是,某些工作负载要求您能够写入容器的可写层.这是存储驱动程序的用武之地. Docker使用可插拔 ...