RxAndroid2.x 源码分析

本贴最后更新于 2941 天前,其中的信息可能已经东海扬尘

RxAndroid 其实就是对 Android 的 handler, looper 及 Message 的封装,使替变为基于观察者模式的调用。理解其源码并不困难,关键在于要先弄清 Andriod 中 handler,looper 及 Message 的关系,才能理清 RxAndroid2.x 的源码。这三者的关系网上的资料一大堆,我就不重复了。
由于 Android UI 的操作是单线程且非线程安全的,因此不可以把耗时的操作放入主线程即 UI 线程中去,否则会引发 ANR 异常,Android 提供了 AsyncTask,及 handler 机制来进行线程切换,RxAndroid 对 handler,looper,Message 进行了封装提供了另外一种思路
在分析源码之前还是先看下如何使用 RxAndroid2.x,2.x 和 1.x 试用方式基本上没啥变化,直接拿官方示例:

public class MainActivity extends Activity { private static final String TAG = "RxAndroidSamples"; //一个存放事件源或被观察者的容器 private final CompositeDisposable disposables = new CompositeDisposable(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main_activity); findViewById(R.id.button_run_scheduler).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { onRunSchedulerExampleButtonClicked(); } }); } @Override protected void onDestroy() { super.onDestroy(); disposables.clear(); } void onRunSchedulerExampleButtonClicked() { disposables.add(sampleObservable() // Run on a background thread //耗时的操作放在io线程中 .subscribeOn(Schedulers.io()) // Be notified on the main thread //回调操作放在主线程 .observeOn(AndroidSchedulers.mainThread()) .subscribeWith(new DisposableObserver() { @Override public void onComplete() { Log.d(TAG, "onComplete()"); } @Override public void onError(Throwable e) { Log.e(TAG, "onError()", e); } @Override public void onNext(String string) { Log.d(TAG, "onNext(" + string + ")"); } })); } //事件源,即被观察者 static Observable sampleObservable() { return Observable.defer(new Callableextends String>>() { @Override public ObservableSourceextends String> call() throws Exception { // Do some long running operation SystemClock.sleep(5000); return Observable.just("one", "two", "three", "four", "five"); } }); } }

界面布局我就不放了,就一个布局文件,而且官方实例当中都有。
核心代码就两行

// Run on a background thread //耗时的操作放在io线程中 .subscribeOn(Schedulers.io()) // Be notified on the main thread //回调操作放在主线程 .observeOn(AndroidSchedulers.mainThread())

怎么样,和原来的代码书写方式比起来是不是简单了很多,只用两行代码!
直接看 RxAndroid2.x 的源码目录结构:
可以看到类不多只有四个类
RxAndroidPlugins,AndroidSchedulers,HandlerScheduler,MainThreadDisposable
这里根据流程来跟踪下源代码,
先看 AndroidSchedulers 中的 mainThread()

public static Scheduler mainThread() { return RxAndroidPlugins.onMainThreadScheduler(MAIN_THREAD); }

可以看到其返回一个 Scheduler,其中 MAIN_THREAD 为主线程的调度器,

static final Scheduler DEFAULT = new HandlerScheduler(new Handler(Looper.getMainLooper()));

内部调用了 RxAndroidPlugins 的 onMainThreadScheduler 方法,其代码如下

public static Scheduler onMainThreadScheduler(Scheduler scheduler) { if (scheduler == null) { throw new NullPointerException("scheduler == null"); } Function<Scheduler, Scheduler> f = onMainThreadHandler; if (f == null) { return scheduler; } return apply(f, scheduler); }

可以看到 onMainThreadHandler 是一个 Fuction 类型,并对齐应用了主线程的调度器,返回给 RxJava 调度

static <T, R> R apply(Function<T, R> f, T t) { try { return f.apply(t); } catch (Throwable ex) { throw Exceptions.propagate(ex); } }

这样就完成的线程的切换,是不是很简单!

HandlerScheduler 提供了在其它线程中刷新 ui 的方法,具体调用看 AndroidSchedulers 的 from(Looper looper)方法,具体操作和 mainThread 方法类似

MainThreadDisposable 提供了资源释放的方法及对主线程的检验方法,也比较简单

总结:其使用核心代码

//耗时的操作放在io线程中 .subscribeOn(Schedulers.io()) // Be notified on the main thread //回调操作放在主线程 .observeOn(AndroidSchedulers.mainThread())

仅需两行代码即可完成线程的切换

  • Java

    Java 是一种可以撰写跨平台应用软件的面向对象的程序设计语言,是由 Sun Microsystems 公司于 1995 年 5 月推出的。Java 技术具有卓越的通用性、高效性、平台移植性和安全性。

    3203 引用 • 8217 回帖

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...

推荐标签 标签

  • BAE

    百度应用引擎(Baidu App Engine)提供了 PHP、Java、Python 的执行环境,以及云存储、消息服务、云数据库等全面的云服务。它可以让开发者实现自动地部署和管理应用,并且提供动态扩容和负载均衡的运行环境,让开发者不用考虑高成本的运维工作,只需专注于业务逻辑,大大降低了开发者学习和迁移的成本。

    19 引用 • 75 回帖 • 686 关注
  • PostgreSQL

    PostgreSQL 是一款功能强大的企业级数据库系统,在 BSD 开源许可证下发布。

    22 引用 • 22 回帖 • 3 关注
  • 分享

    有什么新发现就分享给大家吧!

    248 引用 • 1795 回帖
  • OAuth

    OAuth 协议为用户资源的授权提供了一个安全的、开放而又简易的标准。与以往的授权方式不同之处是 oAuth 的授权不会使第三方触及到用户的帐号信息(如用户名与密码),即第三方无需使用用户的用户名与密码就可以申请获得该用户资源的授权,因此 oAuth 是安全的。oAuth 是 Open Authorization 的简写。

    36 引用 • 103 回帖 • 34 关注
  • Gzip

    gzip (GNU zip)是 GNU 自由软件的文件压缩程序。我们在 Linux 中经常会用到后缀为 .gz 的文件,它们就是 Gzip 格式的。现今已经成为互联网上使用非常普遍的一种数据压缩格式,或者说一种文件格式。

    9 引用 • 12 回帖 • 183 关注
  • Sphinx

    Sphinx 是一个基于 SQL 的全文检索引擎,可以结合 MySQL、PostgreSQL 做全文搜索,它可以提供比数据库本身更专业的搜索功能,使得应用程序更容易实现专业化的全文检索。

    1 引用 • 223 关注
  • SendCloud

    SendCloud 由搜狐武汉研发中心孵化的项目,是致力于为开发者提供高质量的触发邮件服务的云端邮件发送平台,为开发者提供便利的 API 接口来调用服务,让邮件准确迅速到达用户收件箱并获得强大的追踪数据。

    2 引用 • 8 回帖 • 512 关注
  • 思源笔记

    思源笔记是一款隐私优先的个人知识管理系统,支持完全离线使用,同时也支持端到端加密同步。

    融合块、大纲和双向链接,重构你的思维。

    26733 引用 • 111369 回帖 • 1 关注
  • 心情

    心是产生任何想法的源泉,心本体会陷入到对自己本体不能理解的状态中,因为心能产生任何想法,不能分出对错,不能分出自己。

    59 引用 • 369 回帖 • 2 关注
  • SVN

    SVN 是 Subversion 的简称,是一个开放源代码的版本控制系统,相较于 RCS、CVS,它采用了分支管理系统,它的设计目标就是取代 CVS。

    29 引用 • 98 回帖 • 696 关注
  • C++

    C++ 是在 C 语言的基础上开发的一种通用编程语言,应用广泛。C++ 支持多种编程范式,面向对象编程、泛型编程和过程化编程。

    108 引用 • 153 回帖
  • 电影

    这是一个不能说的秘密。

    123 引用 • 608 回帖
  • Sillot

    Insights(注意当前设置 master 为默认分支)

    汐洛彖夲肜矩阵(Sillot T☳Converbenk Matrix),致力于服务智慧新彖乄,具有彖乄驱动、极致优雅、开发者友好的特点。其中汐洛绞架(Sillot-Gibbet)基于自思源笔记(siyuan-note),前身是思源笔记汐洛版(更早是思源笔记汐洛分支),是智慧新录乄终端(多端融合,移动端优先)。

    主仓库地址:Hi-Windom/Sillot

    文档地址:sillot.db.sc.cn

    注意事项:

    1. ⚠️ 汐洛仍在早期开发阶段,尚不稳定
    2. ⚠️ 汐洛并非面向普通用户设计,使用前请了解风险
    3. ⚠️ 汐洛绞架基于思源笔记,开发者尽最大努力与思源笔记保持兼容,但无法实现 100% 兼容
    29 引用 • 25 回帖 • 140 关注
  • CSDN

    CSDN (Chinese Software Developer Network) 创立于 1999 年,是中国的 IT 社区和服务平台,为中国的软件开发者和 IT 从业者提供知识传播、职业发展、软件开发等全生命周期服务,满足他们在职业发展中学习及共享知识和信息、建立职业发展社交圈、通过软件开发实现技术商业化等刚性需求。

    14 引用 • 155 回帖
  • MySQL

    MySQL 是一个关系型数据库管理系统,由瑞典 MySQL AB 公司开发,目前属于 Oracle 公司。MySQL 是最流行的关系型数据库管理系统之一。

    694 引用 • 537 回帖
  • Firefox

    Mozilla Firefox 中文俗称“火狐”(正式缩写为 Fx 或 fx,非正式缩写为 FF),是一个开源的网页浏览器,使用 Gecko 排版引擎,支持多种操作系统,如 Windows、OSX 及 Linux 等。

    7 引用 • 30 回帖 • 367 关注
  • ActiveMQ

    ActiveMQ 是 Apache 旗下的一款开源消息总线系统,它完整实现了 JMS 规范,是一个企业级的消息中间件。

    19 引用 • 13 回帖 • 687 关注
  • Mac

    Mac 是苹果公司自 1984 年起以“Macintosh”开始开发的个人消费型计算机,如:iMac、Mac mini、Macbook Air、Macbook Pro、Macbook、Mac Pro 等计算机。

    167 引用 • 597 回帖
  • golang

    Go 语言是 Google 推出的一种全新的编程语言,可以在不损失应用程序性能的情况下降低代码的复杂性。谷歌首席软件工程师罗布派克(Rob Pike)说:我们之所以开发 Go,是因为过去 10 多年间软件开发的难度令人沮丧。Go 是谷歌 2009 发布的第二款编程语言。

    500 引用 • 1396 回帖 • 252 关注
  • 学习

    “梦想从学习开始,事业从实践起步” —— 习近平

    173 引用 • 541 回帖
  • Quicker

    Quicker 您的指尖工具箱!操作更少,收获更多!

    38 引用 • 158 回帖
  • 新人

    让我们欢迎这对新人。哦,不好意思说错了,让我们欢迎这位新人!
    新手上路,请谨慎驾驶!

    52 引用 • 228 回帖
  • Telegram

    Telegram 是一个非盈利性、基于云端的即时消息服务。它提供了支持各大操作系统平台的开源的客户端,也提供了很多强大的 APIs 给开发者创建自己的客户端和机器人。

    5 引用 • 35 回帖
  • Caddy

    Caddy 是一款默认自动启用 HTTPS 的 HTTP/2 Web 服务器。

    10 引用 • 54 回帖 • 184 关注
  • 快应用

    快应用 是基于手机硬件平台的新型应用形态;标准是由主流手机厂商组成的快应用联盟联合制定;快应用标准的诞生将在研发接口、能力接入、开发者服务等层面建设标准平台;以平台化的生态模式对个人开发者和企业开发者全品类开放。

    15 引用 • 127 回帖
  • IPFS

    IPFS(InterPlanetary File System,星际文件系统)是永久的、去中心化保存和共享文件的方法,这是一种内容可寻址、版本化、点对点超媒体的分布式协议。请浏览 IPFS 入门笔记了解更多细节。

    20 引用 • 245 回帖 • 239 关注
  • OneDrive
    2 引用