安卓组件化框架 CC
- 授权协议: Apache
- 开发语言: Java
- 操作系统: Android
- 软件首页: https://gitee.com/luckybilly/CC
- 软件文档: https://github.com/luckybilly/CC/wiki
- 官方下载: https://gitee.com/luckybilly/CC
软件介绍
CC : ComponentCaller (使用简单但功能强大的安卓组件化框架)
| 模块 | CC | AutoRegister |
| 最新版本 |
原理介绍:Wiki
Demo演示
demo下载(包含主工程demo和demo_component_a组件)
demo_component_b组件单独运行的App(Demo_B)下载
以上2个app用来演示组件打包在主app内和单独以app运行时的组件调用,都安装在手机上之后的运行效果如下图所示
快速理解CC
定义组件:将自身的业务(页面跳转及服务调用等)封装起来提供给外部调用,并返回执行的结果
调用组件:根据组件名称、业务名称及其它参数调用指定组件的指定业务,并获得执行的结果
组件将业务完全隔离在自身内部,仅暴露组件名称(ComponentName)、业务名称(actionName)、参数列表及返回值等信息给外部调用
使用CC的理由
- 集成简单,仅需4步即可完成集成:
1. 在根目录build.gradle中添加自动注册插件
2. 添加apply cc-settings.gradle文件
3. 实现IComponent接口创建一个组件
4. 使用CC.obtainBuilder("component_name").build().call()调用组件
- 完全的代码隔离:CC支持跨app调用组件,开发时组件之间无需互相依赖
组件以app方式独立运行时不需要依赖任何其它组件,从源头上隔离代码
无需担心与主app的相互调用,从一开始组件化改造就可以单组件运行
跟打包在主app中运行是一样的效果,能大大降低组件化改造的难度
- 改造成本低:接入时可基本不改原有代码,原有组件的拆分工作不影响整体组件化改造,参考文章
- 组件层面的AOP支持:可以在组件内部AOP完成登录验证和权限验证等功能,调用方无需关注,参考文章
- Fragment/View的组件化支持:支持组件调用方式获取及后续的功能调用,业务完全内聚,参考文章
- 对Push及jsBridge友好:直接转发对组件的调用即可,参考文章
- 免维护组件列表:使用gradle插件实现组件的自动注册,插拔组件只需修改dependencies依赖即可
- 极低的学习成本,便于推广使用:只需了解一个接口和一个静态方法即可定义组件,只需了解一个链式调用即可调用组件
- 统一的定义方式和调用方式:面向协议来实现和调用组件,类似于移动端跟服务端的通信协议
了解业界开源的一些组件化方案:多个维度对比一些有代表性的开源android组件化开发方案
CC功能列表
1. 支持组件间相互调用(不只是Activity跳转,支持任意指令的调用/回调)
2. 支持组件调用与Activity、Fragment的生命周期关联
3. 支持app间跨进程的组件调用(组件开发/调试时可单独作为app运行)
4. 支持app间调用的开关及权限设置(满足不同级别的安全需求,默认打开状态且不需要权限)
5. 支持同步/异步方式调用
6. 支持同步/异步方式实现组件
7. 调用方式不受实现方式的限制(例如:可以同步调用另一个组件的异步实现功能。注:不要在主线程同步调用耗时操作)
8. 支持添加自定义拦截器(按添加的先后顺序执行)
9. 支持超时设置
10. 支持手动取消
11. 编译时自动注册组件(IComponent),无需手动维护组件注册表(使用ASM修改字节码的方式实现)
12. 支持动态注册/反注册组件(IDynamicComponent)
13. 支持组件间传递Fragment、自定义View等(组件在同一个app内时支持、跨app传递非基础类型的对象暂不支持)
13.1 不仅仅是获取Fragment、自定义View的对象,并支持后续的通信。
14. 尽可能的解决了使用姿势不正确导致的crash,降低产品线上crash率:
14.1 组件调用处、回调处、组件实现处的crash全部在框架内部catch住
14.2 同步返回或异步回调的CCResult对象一定不为null,避免空指针
集成(共4步)
下面介绍在Android Studio中进行集成的详细步骤
1. 添加引用
在工程根目录的build.gradle中添加组件自动注册插件
buildscript {
dependencies {
classpath 'com.billy.android:autoregister:x.x.x'
}
}
2. 在每个module(包括主app)的build.gradle中:
apply plugin: 'com.android.library'
//或
apply plugin: 'com.android.application'
//替换成
apply from: 'https://raw.githubusercontent.com/luckybilly/CC/master/cc-settings.gradle'
//注意:最好放在build.gradle中代码的第一行
默认组件为library,若组件module需要以app单独安装到手机上运行,有以下2种方式:
- 在工程根目录的 local.properties 中添加配置
module_name=true #module_name为具体每个module的名称
- 在module的build.gradle中添加
ext.runAsApp = true
3. 实现IComponent接口创建组件
创建组件(实现IComponent接口,需要保留无参构造方法)
public class ComponentA implements IComponent {
//需保留无参构造方法
@Override
public String getName() {
//组件的名称,调用此组件的方式:
// CC.obtainBuilder("ComponentA").build().callAsync()
return "ComponentA";
}
@Override
public boolean onCall(CC cc) {
Context context = cc.getContext();
Intent intent = new Intent(context, ActivityComponentA.class);
if (!(context instanceof Activity)) {
//调用方没有设置context或app间组件跳转,context为application
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
}
context.startActivity(intent);
//发送组件调用的结果(返回信息)
CC.sendCCResult(cc.getCallId(), CCResult.success());
//返回值说明
// false: 组件同步实现(onCall方法执行完之前会将执行结果CCResult发送给CC)
// true: 组件异步实现(onCall方法执行完之后再将CCResult发送给CC,CC会持续等待组件调用CC.sendCCResult发送的结果,直至超时)
return false;
}
}
4. 调用组件
//同步调用,直接返回结果
CCResult result = CC.obtainBuilder("ComponentA").build().call();
//或 异步调用,不需要回调结果
String callId = CC.obtainBuilder("ComponentA").build().callAsync();
//或 异步调用,在子线程执行回调
String callId = CC.obtainBuilder("ComponentA").build().callAsync(new IComponentCallback(){...});
//或 异步调用,在主线程执行回调
String callId = CC.obtainBuilder("ComponentA").build().callAsyncCallbackOnMainThread(new IComponentCallback(){...});
更多使用方式请戳这里
状态码清单
| 状态码 | 说明 |
|---|---|
| 0 | CC调用成功 |
| 1 | CC调用成功,但业务逻辑判定为失败 |
| -1 | 保留状态码:默认的请求错误code |
| -2 | 没有指定组件名称 |
| -3 | result不该为null。例如:组件回调时使用 CC.sendCCResult(callId, null) 或 interceptor返回null |
| -4 | 调用过程中出现exception,请查看logcat |
| -5 | 指定的ComponentName没有找到 |
| -6 | context为null,通过反射获取application失败,出现这种情况可以用CC.init(application)来初始化 |
| -7 | 跨app调用组件时,LocalSocket连接出错 |
| -8 | 已取消 |
| -9 | 已超时 |
| -10 | component.onCall(cc) return false, 未调用CC.sendCCResult(callId, ccResult)方法 |
混淆配置
不需要额外的混淆配置
自动注册插件
源码:AutoRegister
原理:android扫描接口实现类并通过修改字节码自动生成注册表
JavaScript & jQuery
David Sawyer McFarland / O Reilly / 2011-10-28 / USD 39.99
You don't need programming experience to add interactive and visual effects to your web pages with JavaScript. This Missing Manual shows you how the jQuery library makes JavaScript programming fun, ea......一起来看看 《JavaScript & jQuery》 这本书的介绍吧!
