前言

有点标题党了,其实谈不上什么最佳实践。前段时间公司实行996,所以也没什么时间和精力来更新博客(好吧~我承认是我懒~)。因此这篇文章只是简单的通过两个例子介绍了RxJava在生产环境中的使用。不过本篇中的每个例子我都配上了完整的代码。

按照计划这一期是要介绍RxJava框架结构和设计思想的,但是考虑到Netflix将在十月底发布RxJava2.0正式版;因此决定将RxJava框架结构和设计思想分析放到2.0正式版发布后再做。后续我也会有一系列的文章来介绍RxJava1.x和2.x的区别。

示例一、获取手机上已安装的App

第一个例子我们需要在Android设备上展示已安装的第三方app列表,关于环境搭建、依赖配置、RecyclerView的使用等这些基础内容我就不做陈述了。需要了解的同学可以去GitHub上把项目clone下来看看。这里我主要讲讲如何通过RxJava实现核心功能。

首选我们需要调用系统api来获取所有已安装的app,所以在OnSubscribecall方法中调用getApplicationInfoList()。但是getApplicationInfoList()获取的数据并不能完全满足我们的业务需求:

  1. 由于我们只需要展示手机上已安装的第三方App,因此需要通过filter操作符来过滤掉系统app;
  2. ApplicationInfo并不是我们所需要的类型,因此需要通过map操作符将其转换为AppInfo
  3. 由于获取ApplicationInfo、过滤数据、转换数据相对比较耗时,因此需要通过subscribeOn操作符将这一系列操作放到子线程中来处理;
  4. 而要将信息展示在页面上涉及到UI操作,因此需要通过observeOn操作符将onNextonCompletedonError调度到主线程,接着我们在这些方法中更新UI。

下面是核心代码:

final PackageManager pm = MainActivity.this.getPackageManager();
Observable.create(new Observable.OnSubscribe<ApplicationInfo>() {
@Override
public void call(Subscriber<? super ApplicationInfo> subscriber) {
List<ApplicationInfo> infoList = getApplicationInfoList(pm);
for (ApplicationInfo info : infoList) {
subscriber.onNext(info);
}
subscriber.onCompleted();
}
}).filter(new Func1<ApplicationInfo, Boolean>() {
@Override
public Boolean call(ApplicationInfo applicationInfo) {
return (applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) <= 0;
}
}).map(new Func1<ApplicationInfo, AppInfo>() { @Override
public AppInfo call(ApplicationInfo applicationInfo) {
AppInfo info = new AppInfo();
info.setAppIcon(applicationInfo.loadIcon(pm));
info.setAppName(applicationInfo.loadLabel(pm).toString());
return info;
}
}).subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Subscriber<AppInfo>() {
@Override
public void onCompleted() {
mAppListAdapter.notifyDataSetChanged();
mPullDownSRL.setRefreshing(false);
} @Override
public void onError(Throwable e) {
mPullDownSRL.setRefreshing(false);
} @Override
public void onNext(AppInfo appInfo) {
mAppInfoList.add(appInfo);
}
});

程序执行效果图:

完整的代码我放到了GitHub上,有兴趣大家可以去clone下来自己运行看看。

源码地址:https://github.com/BaronZ88/HelloRxAndroid

示例二、RxJava+Retrofit2实现获取天气数据

RxJava + Retrofit2几乎是Android应用开发的标配了,这个例子中我们就来聊聊这二者是如何配合起来帮助我们快速开发的。

Retrofit2中一个标准的接口定义是这样的:

@GET("weather")
Observable<Weather> getWeather(@Query("cityId") String cityId);

现在有了RxJava,一个基本的网络请求我们便可以这样实现:

ApiClient.weatherService.getWeather(cityId)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Action1<Weather>() {
@Override
public void call(Weather weather) {
weatherView.displayWeatherInformation(weather);
}
});

但有时候可能一开始我们并不知道cityId,我们只知道cityName。所以就需要我们先访问服务器,拿到对应城市名的cityId,然后通过这个cityId再去获取天气数据。

同样的,我们需要定义一个获取cityId的接口:

@GET("city")
Observable<String> getCityIdByName(@Query("cityName") String cityName);

紧接着我们便可以使用无所不能的RxJava来实现需求了。

ApiClient.weatherService.getCityIdByName("上海")
.flatMap(new Func1<String, Observable<Weather>>() {
@Override
public Observable<Weather> call(String cityId) {
return ApiClient.weatherService.getWeather(cityId);
}
}).subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Action1<Weather>() {
@Override
public void call(Weather weather) {
weatherView.displayWeatherInformation(weather);
}
});

哇哦!~ so easy!!!妈妈再也不用担心….

源码地址:https://github.com/BaronZ88/WeatherStyle

WeatherStyle这个项目还在开发中,这个项目不只包含了RxJava和Retrofit的使用,同时还包含MVP、ORMLite、RetroLambda、ButterKnife等等开源库的使用

RxJava1.X的系列文章就到此结束了,由于本人对RxJava的理解有限,这一系列文章中如有错误还请大家指正。在使用RxJava过程中有任何疑问也欢迎大家和我交流。共同学习!共同进步!

好啦,我们RxJava2见!~


如果你喜欢我的文章,就关注下我的知乎专栏或者在 GitHub 上添个 Star 吧!

RxJava系列7(最佳实践)的更多相关文章

  1. 【Yii系列】最佳实践之后台业务框架

    缘起 上面的几章都讲概念了,没有怎么讲到实践的东西,可能会有些枯燥,这很正常的,概念还是需要慢慢啃的,尤其是官网其他的部分,需要狠狠的啃. 什么,你啃不动了?看看官网旁边的那个在线用户吧. 你不啃的时 ...

  2. RxJava系列番外篇:一个RxJava解决复杂业务逻辑的案例

    之前写过一系列RxJava的文章,也承诺过会尽快有RxJava2的介绍.无奈实际项目中还未真正的使用RxJava2,不敢妄动笔墨.所以这次还是给大家分享一个使用RxJava1解决问题的案例,希望对大家 ...

  3. RxJava系列6(从微观角度解读RxJava源码)

    RxJava系列1(简介) RxJava系列2(基本概念及使用介绍) RxJava系列3(转换操作符) RxJava系列4(过滤操作符) RxJava系列5(组合操作符) RxJava系列6(从微观角 ...

  4. RxJava系列5(组合操作符)

    RxJava系列1(简介) RxJava系列2(基本概念及使用介绍) RxJava系列3(转换操作符) RxJava系列4(过滤操作符) RxJava系列5(组合操作符) RxJava系列6(从微观角 ...

  5. RxJava系列4(过滤操作符)

    RxJava系列1(简介) RxJava系列2(基本概念及使用介绍) RxJava系列3(转换操作符) RxJava系列4(过滤操作符) RxJava系列5(组合操作符) RxJava系列6(从微观角 ...

  6. RxJava系列3(转换操作符)

    RxJava系列1(简介) RxJava系列2(基本概念及使用介绍) RxJava系列3(转换操作符) RxJava系列4(过滤操作符) RxJava系列5(组合操作符) RxJava系列6(从微观角 ...

  7. RxJava系列2(基本概念及使用介绍)

    RxJava系列1(简介) RxJava系列2(基本概念及使用介绍) RxJava系列3(转换操作符) RxJava系列4(过滤操作符) RxJava系列5(组合操作符) RxJava系列6(从微观角 ...

  8. RxJava系列1(简介)

    RxJava系列1(简介) RxJava系列2(基本概念及使用介绍) RxJava系列3(转换操作符) RxJava系列4(过滤操作符) RxJava系列5(组合操作符) RxJava系列6(从微观角 ...

  9. OPEN(SAP) UI5 学习入门系列之二: 最佳实践练习(上)

    这篇博文难产了很久,原来是打算一周更新一篇的,上周原计划写MVC,但是写了一半,发现带入了太多的细节,不太符合这个入门系列的主题. 当我们学习一个新的技能的时候,如果一开始就面对大量的细节,很容易陷入 ...

随机推荐

  1. 【Unity3D与23种设计模式】中介者模式(Mediator)

    GoF中定义: 定义一个接口来封装一群对象的互动行为 中介者通过移除对象之间的引用 以减少他们之间的耦合度 并且能改变它们之间的互动独立性 游戏做的越大,系统划分的也就越多 如事件系统,关卡系统,信息 ...

  2. IP地址与域名的关系

    1.IP地址:IP地址是用来唯一标识互联网上计算机的逻辑地址,让电脑之间可以相互通信. 每台连网计算机都依靠IP地址来互相区分.相互联系 2.域名:由于IP地址是数字标识,使用时难以记忆和书写,因此在 ...

  3. firemonkey ListView DynamicAppearance

    Go Up to FireMonkey Application Design Contents [hide]  1 Customizing the List View Appearance Prope ...

  4. Java内存区域之程序计数器--《深入理解Java虚拟机》学习笔记及个人理解(一)

    Java虚拟机程序计数器 在书上的P39页 程序计数器干嘛的? 有了它,字节码解释器才可以知道下一条要执行的字节码指令是哪个. 无论是取下一条指令还是分支.循环.跳转.中断.线程恢复,都需要这个程序计 ...

  5. 堆排序(Java数组实现)

    堆排序:利用大根堆 数组全部入堆,再出堆从后向前插入回数组中,数组就从小到大有序了. public class MaxHeap<T extends Comparable<? super T ...

  6. Spring配置文件中如何使用外部配置文件配置数据库连接

    直接在spring的配置文件中applicationContext.xml文件中配置数据库连接也可以,但是有个问题,需要在url后带着使用编码集和指定编码集,出现了如下问题,&这个符号报错-- ...

  7. 面试题中遇到的算法与js技巧

    近一周在忙着面试,本月第一次更博,甚是想念. 基本上大公司都会要求一些算法或者数据结构类的东西,这方面自己还不是很精通,只能一步一个脚印来积累了. 1.查询字符串获取对象数据,可自行根据需求选择格式, ...

  8. 数据库 --> sqlite3总结

    Sqlite3总结 SQLite,是一款轻型的数据库,是遵守ACID的关系型数据库管理系统,它包含在一个相对小的C库中. sqlite语句 #sqlite3 test.db //设置宽度为2sqlit ...

  9. Java ORM Hibernate 入门笔记

    一.下载 官网地址:http://hibernate.org/ Hibernate下有ORM(关系型数据库).OGM(NoSQL数据库).Search(对象全文检索).Validator的工具. OR ...

  10. maven库

    1.本地仓库 本地仓库是你本地的一个山寨版,只有你看的到,主要起缓存作用. 当你向仓库请求插件或依赖的时候,会先检查本地仓库里是否有.如果有则直接返回,否则会向远程仓库请求,并做缓存. 本地仓库默认在 ...