获得Android组件化方案已经开源,参见Android组件化方案开源。方案的解读文章是一个小的系列,这是系列的第五篇文章:java
上篇文章讲到,AndroidComponent已经进行了UI跳转的升级改造,能够支持路由的自动注册和路由表的自动生成。可是不少使用组件化方案的同窗都表示项目中已经接入ARouter来进行UI跳转,迁移成本比较高。所以我就专门写了这篇文章,讲解一下如何在组件中使用ARouter。android
不论用DDComponent自带的方案仍是ARouter,要作到组件之间自由而且可控的跳转,须要作到下面几点:git
一、路由跳转须要支持传递基本类型和自定义类型(例如Object) 二、路由的跳转须要和组件的生命周期一致,即只有加载的组件才能够跳转,卸载后的组件是不可达的 三、最好生成路由表,组件对外提供的路由能够轻松查阅到github
下面咱们就从配置开始一步步的讲怎么使用ARouterjson
basiclib模块中增长如下依赖,basiclib是组件化框架中共用的依赖库:api
compile 'com.alibaba:arouter-api:1.3.0'
复制代码
在跳转的目标组件的build.gradle中,增长如下配置:bash
android {
defaultConfig {
...
javaCompileOptions {
annotationProcessorOptions {
arguments = [ moduleName : project.getName() ]
}
}
}
}
dependencies {
annotationProcessor 'com.alibaba:arouter-compiler:1.1.4'
...
}
复制代码
在组件化框架中,咱们的示例是从readercomponent跳转到sharecomponent,因此上述配置增长在sharecomponent下面的build.gradle中。app
咱们以“分享图书” 页面为例框架
@Route(path = "/share/shareBook")
public class ShareActivity extends AppCompatActivity {
复制代码
在进入这个页面,须要传入两个参数,一个是String类型的bookName,一个是自定义类型Author的authoride
@Autowired
String bookName;
@Autowired
Author author;
复制代码
因为自定义类型Author须要跨组件传递,咱们知道,DDComponent的核心之处就是在组件之间见了一堵墙,在编译期代码和资源都是彻底隔离的,因此Author必须定义在share组件向外提供的服务中。因此咱们在component中,定义Author类:
public class Author {
private String name;
private int age;
private String county;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getCounty() {
return county;
}
public void setCounty(String county) {
this.county = county;
}
}
复制代码
如今就解决了Author的可见性问题,可是为了能在路由中传递,按照ARouter的要求,还须要本身实现SerializationService:
@Route(path = "/service/json")
public class JsonServiceImpl implements SerializationService {
@Override
public void init(Context context) {}
@Override
public <t> T json2Object(String text, Class<t> clazz) {
return JSON.parseObject(text, clazz);
}
@Override
public String object2Json(Object instance) {
return JSON.toJSONString(instance);
}
@Override
public <t> T parseObject(String input, Type clazz) {
return JSON.parseObject(input, clazz);
}
}
复制代码
这里笔者就遇到了一个坑,原本我把这个类定义在readercomponent中,结果运行以后会报空指针异常。只有我把类移到sharecomponent以后,异常才消失。暂时没找到缘由,可是定义在这里,加入要跳转到readercomponent怎么办呢?
在组件化框架demo中,发起跳转是readercomponent中的ReaderFragment中,demo中列出了两个示例: 普通跳转
private void goToShareActivityNormal() {
Author author = new Author();
author.setName("Margaret Mitchell");
author.setCounty("USA");
ARouter.getInstance().build("/share/shareBook")
.withString("bookName", "Gone with the Wind")
.withObject("author", author)
.navigation();
}
复制代码
以及startActivityForResult
private void goToShareActivityForResult() {
Author author = new Author();
author.setName("Margaret Mitchell");
author.setCounty("USA");
ARouter.getInstance().build("/share/shareMagazine")
.withString("bookName", "Gone with the Wind")
.withObject("author", author)
.navigation(getActivity(), REQUEST_CODE);
}
复制代码
通过上面的操做,已经能够完成UI跳转了。可是若是运行demo就能够发现,此时即便卸载了分享组件,分享书的页面仍是能够进入的,说明生命周期没有同步。在DDComponent自带的方案中是不存在这个问题的,由于跳转的逻辑已经与组件化生命周期绑定在一块儿。 这里就用到ARouter自带的拦截器功能,每一个组件都须要定义一个拦截器,当组件卸载以后须要拦截住该组件的跳转入口。 下面是分享组件拦截器的示例代码:
@Interceptor(priority = 1, name = "分享组件拦截器")
public class ShareInterceptor implements IInterceptor {
public static boolean isRegister;
Context mContext;
@Override
public void process(Postcard postcard, InterceptorCallback callback) {
if (isRegister) {
callback.onContinue(postcard);
} else if ("/share/shareBook".equals(postcard.getPath())
|| "/share/shareMagazine".equals(postcard.getPath())) {
MainLooper.runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(mContext, "分享组件已经卸载", Toast.LENGTH_SHORT).show();
}
});
}
}
@Override
public void init(Context context) {
mContext = context;
}
}
复制代码
这里经过一个isRegister开关来控制拦截器是否生效,为了保证生命周期一致性,在ShareApplike中增长赋值逻辑:
public class ShareApplike implements IApplicationLike {
@Override
public void onCreate() {
ShareInterceptor.isRegister = true;
}
@Override
public void onStop() {
ShareInterceptor.isRegister = false;
}
}
复制代码
可是这里也遇到了两个小坑,不知道是不是ARouter使用不当: (1)添加或者修改拦截器以后,必须卸载重装app才能生效,不管是clean仍是rebuild都是不生效的 (2)拦截器中须要硬编码该组件的全部路由,例如/share/shareBook等,一旦路由发生了改变,必定要记得修改这个地方
这个ARouter暂时没有提供,DDComponent自带的方案增长了这个功能,当组件build生成以后,在根目录生成UIRouterTable文件夹,里面会列出每一个组件向外提供的路由表以及具体参数
auto generated, do not change !!!!
HOST : share
分享杂志页面
/shareMagazine
author:com.luojilab.componentservice.share.bean.Author
bookName:String
分享书籍页面
/shareBook
author:com.luojilab.componentservice.share.bean.Author
bookName:String
复制代码
这点对于组件的协同开发是比较重要的,毕竟跳转以前翻阅别人的代码是件比较费事的工做
上面的代码已经发布DDComponent的master-arouter分支,欢迎你们使用,源码地址: github.com/mqzhangw/An…