獲得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…