概述

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. [Atcoder Regular Contest 065] Tutorial

    Link: ARC065 传送门 C: 最好采取逆序贪心,否则要多考虑好几种情况 (从前往后贪心的话不能无脑选“dreamer”,"er"可能为"erase"/ ...

  2. AtCoder - 1999 Candy Piles

    Problem Statement There are N piles of candies on the table. The piles are numbered 1 through N. At ...

  3. BZOJ 4059 [Cerc2012]Non-boring sequences(启发式分治)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=4059 [题目大意] 一个序列被称为是不无聊的,仅当它的每个连续子序列存在一个独一无二的 ...

  4. 【思路】Aizu - 1367 - Rearranging a Sequence

    给你一个1~n排好的数组,每次提一个数到最前面,问你最后形成的序列. 就把他的输入顺序倒过来输出即可.没出现过的再按原序输出. #include<cstdio> using namespa ...

  5. 原生js操作HTML DOM

    先上图 1.一些常用的方法 obj.getElementById() 返回带有指定 ID 的元素. obj.getElementsByTagName() 返回包含带有指定标签名称的所有元素的节点列表( ...

  6. .net中的泛型

    泛型把类或方法的类型的确定推迟到实例化该类或方法的时候 ,也就是说刚开始声明是不指定类型,等到要使用(实例化)时再指定类型 泛型可以用于  类.方法.委托.事件等 下面先写一个简单的泛型 public ...

  7. PASCAL 的开源工具

    PASCAL 的开源工具: 1)free pascal  代码编译器     http://www.freepascal.org/ 2)lazarus 图形界面开发工具   http://www.la ...

  8. MLP 之手写数字识别

    0. 前言 前面我们利用 LR 模型实现了手写数字识别,但是效果并不好(不到 93% 的正确率). LR 模型从本质上来说还只是一个线性的分类器,只不过在线性变化之后加入了非线性单调递增 sigmoi ...

  9. logback中打印sql语句

    To log SQL statements for particular mybatis mapper set DEBUG (TRACE to see query parameters and res ...

  10. Git系列三之GitHub使用方法

    GitHub 是一个面向开源及私有软件项目的托管平台,因为只支持 Git 作为唯一的版本库格式进行托管,故名 GitHub. GitHub 于 2008 年 4 月 10 日正式上线,除了 Git 代 ...