项目主页:https://github.com/bboylin/Pigeon
Features
- Pigeon实现了activity间通过URL跳转和参数依赖注入,同时劫持了onActivityResult,改成接口回调
- Pigeon提供了基于特定uri规则的dispatch机制,用于支持互不依赖的module之间接口调用以及统一js调用Android入口
- Pigeon利用注解实现了IOC依赖注入,方便了IOC管理
- Pigeon没有使用APT,也没有使用反射,支持增量编译
- Pigeon支持Deep Link,从浏览器跳转应用任意页面
usage
1. 如何引用
1.1 在project的build.gradle添加
1 | buildscript { |
1.2 在app的build.gradle中添加
1 | // 注意,此项应该加在Android配置项后面,不然可能报错。 |
1.3 组件化项目在base module的build.gradle添加
1 | // 把 a b c替换成最新的release版本号 |
非组件化项目则是直接在app module的build.gradle添加
2. Activity路由使用
2.1 使用注解标记要跳转的activity
1 | "pigeon://sample/SampleLibActivity") ( |
2.2 构造postcard跳转
1 | Postcard postcard = PostcardBuilder.newInstance(context, "pigeon://sample/SampleLibActivity") |
2.3 参数的依赖注入
1 | // 在要跳转的activity中使用Bind注解标记注入的字段 |
2.4 onActivityResult改成接口回调
1 | setOff( Postcard postcard, OnResultListener onResultListener) |
3. Scheme Dispatch使用
3.1 Pigeon基于一套Scheme规则进行分发:
1 | // 规则 |
其中version部分遵循正则:v\d+ 数字越大表示版本越高,path部分可自由组合,建议按照module/submodule/…../action这种细分。query部分的key和value在dispatch到对应的dispatcher的时候会进行url decode,同时以hashmap形式提供。
3.2 可通过注解添加Dispatcher和Interceptor , 在dispatch scheme的时候进行拦截和分发处理:
1 | // 每个Dispatcher都有个对应的path,uri dispatch的时候会解析出path,根据path找到对应Dispatcher |
3.3 在应用启动的时候Pigeon需要初始化:
1 | // 初始化的时候可以绑定dispatcher和interceptor,以及校验scheme有效性等。 |
3.4 分发的时候使用dispatch方法即可:
1 | public static boolean dispatch(@NonNull Context context, @NonNull String uri); |
4. IOC依赖注入
通过Autowired和Inject两个注解标记需要注入的类和方法,示例:
1 |
|
然后通过Provider注解标记要注入的实例,1
2
3
4
5
6
7
8
9
10
11
12
13
public class AppRuntime implements IAppRuntime {
public Context getAppContext() {
return DemoApplication.getInstance();
}
public void showUniversalToast(Context context, String text) {
UniversalToast.makeText(context, text, UniversalToast.LENGTH_SHORT, UniversalToast.EMPHASIZE)
.showWarning();
}
}
在最终生成的APK里,AppRuntimeProvider注入后的代码成了:
1 |
|
其中AppRuntime_Factory
是pigeon自动生成的提供AppRuntime
单例的工厂类
Principle
5.1 why not apt
一是因为gradle 4.7才开始部分支持apt的增量编译,二是因为apt一次只能对单个module生效,最后还得需要开发一个gradle插件合并所有module的路由表。
基于此,pigeon直接利用javassist在transform阶段生成路由表,一举两得。
5.2 about IOC
组件化开发中,有时候会出现下层module需要调用上层module接口的现象,例如获取App Context;例如调用登陆,视频播放等功能,而这几个功能在上层module。
这时候就需要进行控制反转。通过依赖注入来实现控制反转能减少许多冗余的公式化代码,另外也能减少模块间的耦合。
5.3 about scheme
好处一是方便调用不依赖的module的服务,方便组件之间解耦;二是可以统一js和Android通信的桥梁,只需要绑定一个方法,根据传入的不同scheme就能调用不同服务。这个分发过程已经由pigeon完成,
5.4 about RouteMap
路由表是在transform阶段扫描RouteNode注解生成,activity内参数注入通过扫描Bind注解,针对每个activity生成对应的Injector类,最终生成一个InjectorDispatcher类根据要跳转的activity名找到对应Injector来执行参数注入。
具体用法可以参考demo代码。