概述

RxJava API示例代码,可离线查看rxjava1.0大部分API的marble图,描述,示例代码,并支持示例代码实时输出及展示执行结果。

详细

一、项目概述

本Demo是为了方便大家了解RxJava的API,我将所有的RxJava API(至少是官方文档中提到的)都写在一个android apk中,并在其中附以功能描述,代码示例,marble-diagram(Rx用来描述数据及其处理流程的图), 以及一些使用场景. 所有的资料都是在APK中,使用的时候不会消耗任何流量,而且你可以在任何时候任何地方学习使用.

示例程序的特点如下:

1. API涵盖全面: 包含了核心库及所有扩展实现库200个左右的API.

2. 数据本地化,无需流量: 示例中的所有数据和图片都是本地加载的,所以无需消耗流量.

3. 示例代码都是从源码中直接生成,所以看起来跟代码直接运行的效果是一样的

二、主界面展示

上图为整个Demo的运行示例截图:

  1. 左边为Rxjava主要组件及运算符类别入口

  2. 右边为单个运算符的marble-diagram, 详细的运算符列表,代码示例以及代码的执行结果。

  3. 点击相应的运算符,界面会切换到该运算符的marble-diagram以及示例代码,同时会执行该代码,将执行结果输出到结果区。

三、代码实现

在整个Demo中,主要部分就是RxJava API运算子的呈现,包括marble图,API描述,示例代码,运算结果的展现

及不同运算子切换的交互。

所有的UI组成部分都是以插件的形式插入到Demo的UI体系中,设计图如下:

APIBaseActivity: API详情主Activity,包含了重定向输出结果到结果view以及整合DisplayPluginManager中所有View的展示的功能。

DisplayPluginManager: 管理所有的展示Plugin。

Plugin: 展示Plugin的接口类,主要负责根据不同的操作符ID提供不同的插件View。

MarbleDiagramPlugin: Marble图展示插件。

DescriptionPlugin: API描述展示插件。

SampleCodePlugin: 示例代码展示插件。

下边详细介绍这四部分的核心实现:

Marble图

marble图的地址是我在看官方文档的时候,手动扣取的,所有地址都保存在项目的MarbleDiagramPlugin.java中

最初demo使用的是动态获取marble图地址,由于原图需要消耗流量且图片较大,所以我是将所有图片从网络拉取到本地直接打包到apk中,而且在这个过程中对图片进行了进一步的打包压缩。

  1. 读取marble地址配置

# 将原来的注册地址的代码块处理并读取出来
def ProcessRegisterBlock(lines):
if len(lines) == 0:
return None
mb = []
for line in lines:
line = line.strip('\r\n ,);')
line = line.replace('\"','');
if len(line) < 10 or not line.startswith('http'):
continue mb.append(line)
return mb # 查找到Constants对应的Key
def FindKey(line):
start = line.find('Constants.')
end = line.find(',',start)
return line[start: end] # 将名称转化为android的资源描述符名称
def Url2Id(url):
start = url.rfind('/')
if start < 0:
return None
return 'R.drawable.' + url[start + 1:].replace('.','_').lower() codes = {}
# 拼装待生成的目标代码的路径
dest = os.path.join('app','src','main','java','union','uc','com','rxjava_example','plugin')
if not os.path.exists(dest):
os.path.makedirs(dest) key = ""
# 打开marble图地址配置源码文件,并逐行扫描处理
with open(os.path.join(dest, 'MarbleDiagramPlugin.java'), 'r') as input:
block = []
find_add = False
for line in input:
if len(line.strip()) == 0:
continue
if line.find('add(Constants.') >= 0:
find_add = True
if len(block) > 0:
code= ProcessRegisterBlock(block)
codes[key] = code
block = []
key = FindKey(line)
http_start = line.find('\"http')
if http_start >= 0:
http_end = line.find('\"', http_start + 1)
if http_end >= 0:
block.append(line[http_start:http_end])
elif find_add:
block.append(line)
if find_add and len(block) > 0:
code= ProcessRegisterBlock(block)
codes[key] = code

2. 生成Marble图资源配置文件

# 新建marble图资源配置文件
with open(os.path.join(dest,'MarbleDiagram.java'),'w') as output:
# 生成header
header = '''
package union.uc.com.rxjava_example.plugin; import java.util.HashMap;
import java.util.Map;
import union.uc.com.rxjava_example.contants.Constants;
import union.uc.com.rxjava_example.R;
public class MarbleDiagram{
private Map<String, Integer[]> mCodes = new HashMap<>();
public MarbleDiagram(){
'''
footer = '''
}
public Integer[] get(String key){
return mCodes.get(key);
}
private void add(String key, Integer... urls) {
mCodes.put(key, urls);
}
}
'''
output.write(header)
# 生成footer
for key,code in codes.items():
if code == None:
continue
s = ""
if len(code) == 1:
code0 = Url2Id(code[0])
s = '\nadd(%s,%s);' % (key, code0)
elif len(code) == 2:
code0 = Url2Id(code[0])
code1 = Url2Id(code[1])
s = '\nadd(%s,%s,%s);' % (key, code0, code1)
elif len(code) == 3:
code0 = Url2Id(code[0])
code1 = Url2Id(code[1])
code2 = Url2Id(code[2])
s = '\nadd(%s,%s,%s,%s);' % (key, code0, code1, code2)
elif len(code) == 4:
code0 = Url2Id(code[0])
code1 = Url2Id(code[1])
code2 = Url2Id(code[2])
code3 = Url2Id(code[3])
s = '\nadd(%s,%s,%s,%s,%s);' % (key, code0, code1, code2, code3)
output.write(s)
output.write(footer)
#下载图片
dir_drawable = os.path.join('app', 'src', 'main', 'res', 'drawable')
for key,code in codes.items():
if code != None:
for c in code:
os.system('wget %s -P imgs' % (c ))
# 重命名图片
for root, dirs, files in os.walk('imgs'):
for file in files:
src = os.path.join(root,file)
dest = os.path.join(dir_drawable, file.lower().replace('.', '_') + '.png')
os.rename(src, dest)

3. 压缩图片,为减小API尺寸,对marble图进行了简单压缩

dir_drawable = os.path.join('app', 'src', 'main', 'res', 'drawable')
for root, dirs, files in os.walk(dir_drawable):
for file in files:
if not file.endswith('.png'):
continue
src = os.path.join(root,file)
img = Image.open(src)
img = img.resize((400,200),Image.ANTIALIAS)
img.save(src)
del img

API描述

API描述UI插件的实现是在DescriptionPlugin中,该Plugin主要是根据操作符id生成TextView并设置内容文本。

public class DescriptionPlugin implements DisplayPluginManager.Plugin {
@Override
public Tuple.Tuple2<Observable<View>, View> getView(final Context context, String key) {
// 创建描述TextView, 为提高内存性能,避免无效引用,使用WeakReference.
final TextView textView = new TextView(context);
final Reference<TextView> ref = new WeakReference<>(textView);
Observable<View> o = Observable.just(key)
.map(new Func1<String, Integer>() {
@Override
public Integer call(String s) {
// 如果资源列表为空,则加载资源列表
if (mKeyToResource == null) {
load();
}
// 读取id对应的资源文本内容
return mKeyToResource.get(s);
}
}).map(new Func1<Integer, View>() {
@Override
public View call(Integer integer) {
// 更新TextView 文本
textView.setText(integer);
return textView;
}
}); return new Tuple.Tuple2<>(o, (View) textView);
}

API示例代码

示例代码的实现是在SampleCodePlugin中,其实现逻辑是根据操作符id读取示例代码,并使用markdown view渲染。

public class SampleCodePlugin implements DisplayPluginManager.Plugin {
@Override
public Tuple.Tuple2<Observable<View>, View> getView(final Context context, String key) {
// 创建Markdown view,使用weakreference,为了处理嵌入式touch事件的处理冲突,还需要重写其
onTeouchEvent方法。
MarkdownView markdownView = new MarkdownView(context){
@Override
public boolean onTouchEvent(MotionEvent event) {
requestDisallowInterceptTouchEvent(true);
return super.onTouchEvent(event);
}
};
markdownView.setBackgroundColor(Color.LTGRAY);
final Reference<MarkdownView> ref = new WeakReference<>(markdownView);
Observable<View> o = Observable.just(key)
// .observeOn(Schedulers.io())
.map(new Func1<String, String>() {
@Override
public String call(String s) {
// 根据id获取示例代码,示例代码已经提前生成。
return mSampleCode.get(s);
}
})
.observeOn(Schedulers.from(UIThreadExecutor.SINGLETON))
.map(new Func1<String, View>() {
@Override
public View call(String s) {
// 使用markdownview加载示例代码
MarkdownView mv = ref.get();
if (mv != null) {
mv.loadMarkdown(s);
}
return mv;
}
});
return new Tuple.Tuple2<>(o, (View) markdownView);
}

根据操作符切换

每当点击操作符之后,界面更新的同时,程序也会执行该操作符对应的示例代码,并将示例代码结果输出到界面,输出的形式是重定向日志的方式,即将程序输出结果逐行append到结果输出界面。

四、项目结构

如上图,为整个demo工程的项目结构截图,为一个通用的android项目结构图,其中的

README.md:为Rxjava及部分项目的介绍。

*.py文件:为自动生成marble图及示例代码的脚本。

五、其他

本示例从逻辑到实现概要介绍如上,详细内容,请参考demo源码。

注:本文著作权归作者,由demo大师发表,拒绝转载,转载需要作者授权

RxJava API使用示例的更多相关文章

  1. ASP.NET Web API 开篇示例介绍

    ASP.NET Web API 开篇示例介绍 ASP.NET Web API 对于我这个初学者来说ASP.NET Web API这个框架很陌生又熟悉着. 陌生的是ASP.NET Web API是一个全 ...

  2. 老李推荐:第3章3节《MonkeyRunner源码剖析》脚本编写示例: MonkeyImage API使用示例 1

    老李推荐:第3章3节<MonkeyRunner源码剖析>脚本编写示例: MonkeyImage API使用示例   在上一节的第一个“增加日记”的示例中,我们并没有看到日记是否真的增加成功 ...

  3. 老李推荐: 第3章1节《MonkeyRunner源码剖析》脚本编写示例: MonkeyRunner API使用示例

    老李推荐: 第3章1节<MonkeyRunner源码剖析>脚本编写示例: MonkeyRunner API使用示例   MonkeyRunner这个类可以说是编写monkeyrunner脚 ...

  4. HTML 百度地图API调用示例源码

    <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content ...

  5. Jedis API 详细示例

    Jedis API 详细示例 https://www.jianshu.com/p/125357ee7651

  6. Java8新特性时间日期库DateTime API及示例

    Java8新特性的功能已经更新了不少篇幅了,今天重点讲解时间日期库中DateTime相关处理.同样的,如果你现在依旧在项目中使用传统Date.Calendar和SimpleDateFormat等API ...

  7. 实验6、Flask API使用示例和拓展

    实验介绍 1. 实验内容 Flask 提供了多种API拓展,本节我们主要学习基于RESTful的Flask应用程序设计 2. 实验要点 学习和掌握多种RESTful的设计模式 3.实验环境 Cento ...

  8. SharePoint 2013 Search REST API 使用示例

    前言:在SharePoint2013中,提供Search REST service搜索服务,你可以在自己的客户端搜索方法或者移动应用程序中使用,该服务支持REST web request.你可以使用K ...

  9. ASP.NET Web API 入门示例详解

    REST服务已经成为最新的服务端开发趋势,ASP.NET Web API即为.NET平台的一种轻量级REST架构. ASP.NET Web API直接借鉴了ASP.NET MVC的设计,两者具有非常类 ...

随机推荐

  1. 【POJ 2409】 Let it Bead(置换、burnside引理)

    Let it Bead "Let it Bead" company is located upstairs at 700 Cannery Row in Monterey, CA. ...

  2. 「NOI2018」屠龙勇士

    「NOI2018」屠龙勇士 题目描述 小\(D\)最近在网上发现了一款小游戏.游戏的规则如下: 游戏的目标是按照编号\(1-n\)顺序杀掉\(n\) 条巨龙,每条巨龙拥有一个初始的生命 值ai .同时 ...

  3. BZOJ 1109 [POI2007]堆积木Klo(树状数组)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=1109 [题目大意] Mary在她的生日礼物中有一些积木.那些积木都是相同大小的立方体. ...

  4. 【并查集】Gym - 101128B - Black Vienna

    有26张牌(A~Z),其中三张被拿走了.其余23张被分发给了两个人.给你m次调查结果,一次调查结果是对其中一个人询问一对牌,他会告诉你他有这对牌的几张(0~2).问你有多少种被拿走的牌的组合. 三重循 ...

  5. es进行聚合操作时提示Fielddata is disabled on text fields by default

    在进行派粗前,先执行以下操作 { "properties": { "updatedate": { "type": "text&qu ...

  6. [转]oracle 数据库、表空间、实例、服务之间的关系

    1.每个DATABASE--可包含多个INSTANCE--每个INSTANCE可包含多个TABLESPACE和USER等(授予USER读写TABLESPACE的权限)--每个TABLESPACE可包含 ...

  7. <摘录>算法策略的总结

    策略是面向问题的,算法是面向实现的. 一.不同算法策略特点小结 1.贪心策略 贪心策略一方面是求解过程比较简单的算法,另一方面它又是对能适用问题的条件要求最严格(即适用范围很小)的算法. 贪心策略解决 ...

  8. 调整Chrome中文字体为雅黑

    几天试了一下Chrom发布的Chrome 37,感觉所谓的Direct2D渲染还是有些效果的,但这只体现在英文上,中文的宋体还是非常的不舒服,便试着将其替换成了雅黑,这里介绍一下相关方法. Chrom ...

  9. 【荐】利用NAT、Host-Only双虚拟网卡,实现Virtual Box中CentOS5.x联网

    一.虚拟机与主机互联,通常有三种方式,详细介绍请看: VMware虚拟机三种网络模式(Bridged,Nat,Host-only)区别详解 二.通过网络共享,Host-Only联网,详细案例请看: W ...

  10. 在ios中微信video和audio无法自动播放解决方案

    WeixinJSBridgeReady页面初始化的时候会执行 document.addEventListener("WeixinJSBridgeReady", function ( ...