专栏名称: 开发者全社区
分享和推送Java/Android方向的技术和文章,让你成为这方面的大牛,让你每天都成长一点。同时,我们也会邀请BAT的大牛分享原创!
目录
相关文章推荐
鸿洋  ·  Google 为何设计了如此难用的 ... ·  昨天  
鸿洋  ·  Android14 WMS/AMS ... ·  2 天前  
stormzhang  ·  真正该刺激的是收入 ·  3 天前  
鸿洋  ·  Android主线程锁监控的一种方案 ·  1 周前  
stormzhang  ·  打工人维权,难吗? ·  1 周前  
51好读  ›  专栏  ›  开发者全社区

开源的ToyBricks——Android项目模块化解决方案

开发者全社区  · 公众号  · android  · 2017-05-09 07:23

正文

相关阅读:

吊炸天!74款APP完整源码!

Android架构之App 模块化实战经验总

Android经久不衰最受欢迎的开源库整理,你一定用过10个以上,架构师必备

ToyBricks源码:   

https://github.com/SnowdreamFramework/ToyBricks

ToyBricks背景

我始终认为,在高内聚,低耦合的原则下,进行组件化,模块化,插件化都是移动应用开发的趋势。

为什么这么说呢?下面我们举个栗子:
大家都知道,以前Android应用开发中,可以使用HttpClient或者HttpUrlConnection来进行http访问。这里假设有一个耦合严重,但代码量巨大的项目,使用了基于HttpClient封装的loopj/android-async-http来进行http访问。但是,后来,Google明确支持使用HttpUrlConnection。此时,经过调研,你们觉得square/okhttp基于HttpUrlConnection,符合你们的要求。

现在,不管是否将HttpClient替换成okhttp,你们都可能面临以下困境:

  1. 需求都做不完,根本没有排期做这个替换。于是,你们面临离google的支持越来越远,离风险越来越近的困境;

  2. 辛辛苦苦耗费人力将HttpClient替换成okhttp。但由于两者变化很大,需要投入很多测试资源,来重新确认这些接口是否正常访问。一旦出现问题,还需要安排研发资源,去一一排查。

  3. 替换的工作量太大。替换一部分之后,发现没有足够人力去继续完成。于是,替换终止。整个工程又变得混乱和臃肿,同时包含了两种http的封装库和调用。


模块化可以有效解决这些问题。通用的做法,是按照业务,功能等将整个项目分成不同的模块,由不同的研发测试小组负责。
每个模块又分为接口和实现两个部分。接口部分提供给模块外部调用,而实现部分则禁止来自外部的调用。



那么,如何将模块的接口和实现部分关联起来呢?通过APT工具,可以轻松地将接口部分和实现部分关联起来。

APT,即Annotation Processing Tool,可以理解为“编译时注解处理器工具”。

官方说明:
“The apt tool is a command-line utility for annotation processing. It includes a set of reflective APIs and supporting infrastructure to process program annotations (JSR 175). These reflective APIs provide a build-time, source-based, read-only view of program structure. They are designed to cleanly model the Java programming language's type system after the addition of generics (JSR 14).”

简单理解如下:
apt工具是javac工具的一部分。在编译时,apt工具首先会扫描工程下Java源码中的编译时注解,再根据预先定义的编译时注解处理工具,生成指定的Java源码文件。紧接着,生成的Java源码文件和之前项目下的Java源码一起,由javac工具来编译成class。

但是,APT有一个局限性,就是只会扫描Java源码,不会扫描jar ,aar 和class 。也就是说,所有模块需要以源码形式存在。而现在通用的做法是,将模块打包成jar或者aar,发布到Maven库,再由其他模块自行引用。

有没有办法将APT的这种功能和特性延伸到jar和aar呢?
于是,ToyBricks应运而生。

ToyBricks简介

ToyBricks简介

ToyBricks是一个Android项目模块化的解决方案,主要包括四个部分,APT注解,APT注解处理器,ToyBricks插件(Gradle Plugin),ToyBricks库。

ToyBricks(积木)(以下简称ToyBricks)是基于面向积木方法论构建的、面向Java开发(尤其是RIA应用)的开源开发平台, 旨在提供给开发者一个简单易用、高效率、高产品质量、易扩展的开源平台,“像搭积木一样开发软件”。


其中:

  1. APT注解,主要定义了两个注解:Interface(接口,例如:IText),Implementation (实现,例如:TextImpl) 

  2.  APT注解处理器,在javac编译java源码之前。APT注解处理器会扫描Java源码中带有上面两个注解的接口和类,并且生成一个json文件, ToyBricks.json.

  3. ToyBricks插件(Gradle Plugin),负责ToyBricks.json的打包,合并,生成Java源文件等工作

  4. ToyBricks,提供对外调用方法。通过参数传入接口,返回相应的实现。


ToyBricks原理分析

下面以接口IText和实现TextImpl为例,简单介绍下ToyBricks原理。

主要分为两个部分:

Android Library(最终可能打包成jar,aar,并发布到maven库)

如果工程是Android库模块,则主要流程如下:
1.在javac编译java源码之前,由APT注解处理器扫描Java源码中带有上面两个注解的接口和类,生成ToyBricks.json。


2.在打包jar,aar的时候,由ToyBricks插件(Gradle Plugin)提前处理,保证ToyBricks.json能被拷贝进去jar包或者aar包的根目录下,并随同一起分布到maven仓库。

Android Application

如果工程是Android应用模块,则主要流程如下: 

  1. 第一步,和Android Library第一步一致。

  2. Javac编译Java源代码

  3. 扫描所有依赖的库文件,过滤出所有包含ToyBricks.json文件的jar包或者aar包,并且提取出来。提取完毕后,合并所有的ToyBricks.json文件,成为一个ToyBricks.json。

  4. 将最终的ToyBricks.json按照预定规则生成一个Java源码文件.文件名为: InterfaceLoaderImpl.java

5.再次使用Javac工具编译InterfaceLoaderImpl.java文件。
6.这个文件就类似字典索引,通过这个文件,就可以通过传入接口,来查找对应的实现类。

不仅仅支持Android

ToyBricks解决了很多长期困扰Java开发者的问题,如:


1)开发所应用的“平台”都是拼凑而成而非真正意义上的整合解决方案 。

事实上,很多软件公司的平台都是用开源软件“混搭”而成,典型的,如 SSH(Struts+Spring+Hibernate)、FSH(Flex+Spring+Hibernate)等,这种混搭方案天然的割裂了作为组件 的完整性,因为很多组件是横跨展现、业务逻辑甚至持久层的 ;


2)JavaEE中Web开发规范的缺陷。

在当前的JavaEE开发中,作为一个功能,页面与业务逻辑、配置等文件是分散在不同地方的 (页面jsp、 html、js、css、图片等等一般放在工程rootFolder的某个文件夹中;业务逻辑放在classpath下;配置文件有时候要放在WEB-INF 文件夹中),这种分散天然的破坏了作为一个功能的“聚合”要求 (事实上在我们日常的设计工作中,人们追求松耦合更甚于高聚合),我们很多时候是希望作为一个功能的全部文件放在一起的;
这种分散式的结构直接导致了“一个功能或模块打包形成一个jar文件作为产出物”的困难 。


3)多个功能、模块之间的冲突问题 。

jar冲突是最显而易见的了,不同模块要求同一jar的版本可能不同,由于缺乏像OSGI那样的单元(OSGI中为Bundle) 隔离机制,所以只能一方向另一方妥协;


4)编程模型复杂、学习难度高 。

无论Struts的MVC、Flex的组件模型、Spring的IOC/AOP、Hibernate的ORM等等,其学习与应用 都是有一定难度的;


5)缺乏组件模型或组件模型复杂。

可复用的资源积累是一个软件企业知识资产积累的重要组成部分 ,以JSP的Tag为例,目前很多企业内部只有少部分高 水平技术人员被授权开发公司应用的标签库,这严重限制了可复用资源的积累;

 

6)缺乏清晰的功能、模块边界。

能、模块之间高度耦合,且耦合分散在各个角落,导致模块拆分困难 ;

 

ToyBricks目前提供的功能

1)ToyBricks JavaBean运行容器;
2)Aquarell模板引擎;
3)RIA实现;
4)常规组件库:

  1】  UI 类

      1.   按钮(支持下拉菜单、状态控制、图标自动匹配)

      2.  Text 编辑器(支持自定义扩展、校验器等)

      3.  TextArea 编辑器(支持自定义扩展、校验器等)

      4. Combox 编辑器(可组合其他编辑器、支持即时搜索(可配置客户端或服务端数据源)、校验器等等)

      5.  日期(时间)选择器(支持可配置的年月、年月日、年月日时间、时间等等选择)

      6. HTML 编辑器(基于 CKEditor ,支持各类常规操作,可通过配置 mode (模式)为 basic/cms 等来批量选择功能按钮)

      7.  选择树编辑器(支持单选、多选、节点锁定等等)

      8.  文件上传(基于 Flex 技术、支持单个与多文件上传、限制类型、大小、各类回调函数等等)

      9.  代码高亮显示

      10.  数据表格(支持列排序、列搜索、单元格编辑、分页、行菜单、表格菜单、预定义模板按钮等等)

      11.  自由格式表格

      12.  Tree (支持节点懒加载、工具条按钮扩展、节点菜单等等)

      13.   表单( Form )(支持编辑器自由布局与格式化布局、支持值自动分发与收集、统一校验等等)

      14.  菜单(无限层级支持、状态控制、动态数据源等等)

      15.  菜单条

      16.  TabBox (支持 Tab 懒加载、锁定等)

      17.  工具条

      18.   对话框

      19.  CSS 引用(支持全局(页面)唯一引用)

      20.  JavaScript 引用(支持全局(页面)唯一引用)

      21.  Splitter

      22.  图标库(预置了上百种各类图标,提供非常简单的扩展机制)

  2】  数据源(基于 Toplink ( JPA ),支持基于 JPA 规范的 ORM ,支持多数据源,域对象自动发现等等)

  3】  Dao (同时支持基于 JPA 规范与原生 SQL )

 

ToyBricks的特性

1)开发者只需要掌握简单的Java、Html(简单的Javascript及CSS)即可 ;
2)搭积木的开发体验 ,开发者只需要编写必须的代码;
3)ToyBricks提供了丰富的组件库 ;
4)桌面级的用户产品体验 ;
5)应用即组件、一切皆组件 。事实上,实际开发中有约50%以上都是重复的功能,基于ToyBricks体系,您可以将您想要的一切封装成组件;
6)一个功能(模块、甚至系统)可以打包成一个jar文件,边界清晰 ;
7)运行时隔离;
8)比OSGI更简单的扩展机制 (套娃模型);
9)搭配ToyBricks的WebOS平台,您已经拥有了一套完整的系统;

 

ToyBricks平台结构

 

 

总结

与APT工具相比,ToyBricks能够将接口和实现之间的关系进行持久化,存储在jar和aar中,并随之发布到Maven仓库,实现接口和实现的彻底分离。

如果您对ToyBricks有什么问题或者建议,欢迎通过后面的联系方式联系我。

参考资料:

  1. SnowdreamFramework/ToyBricks

  2. Annotation Processing Tool (apt)

  3. ANNOTATION PROCESSING 101

  4. Annotation-Processing-Tool详解

  5. Java注解处理器

  6. 什么是高内聚、低耦合?


作者:snowdream  

Blog: http://snowdream.github.io/blog  

参见:http://www.iteye.com/news/23015


看完本文有收获?请分享给更多人


Java和Android架构

欢迎关注我们,一起讨论技术,扫描和长按下方的二维码可快速关注我们。搜索微信公众号:JANiubility。

公众号:JANiubility