git地址:ARouter
集中式的URL管理:談到集中式的管理,總是比較蛋疼,多人協(xié)同開發(fā)的時候,大家都去AndroidManifest.xml中定義各種IntentFilter,使用隱式Intent,最終發(fā)現(xiàn)AndroidManifest.xml中充斥著各種Schame,
各種Path,需要經(jīng)常解決Path重疊覆蓋、過多的Activity被導(dǎo)出,引發(fā)安全風(fēng)險(xiǎn)等問題
可配置性較差:Manifest限制于xml格式,書寫麻煩,配置復(fù)雜,可以自定義的東西也較少
跳轉(zhuǎn)過程中無法插手:直接通過Intent的方式跳轉(zhuǎn),跳轉(zhuǎn)過程開發(fā)者無法干預(yù),一些面向切面的事情難以實(shí)施,比方說登錄、埋點(diǎn)這種非常通用的邏輯,在每個子頁面中判斷又很不合理,畢竟activity已經(jīng)實(shí)例化了
跨模塊無法顯式依賴:在App小有規(guī)模的時候,我們會對App做水平拆分,按照業(yè)務(wù)拆分成多個子模塊,之間完全解耦,通過打包流程控制App功能,這樣方便應(yīng)對大團(tuán)隊(duì)多人協(xié)作,互相邏輯不干擾,這時候只能依賴隱式Intent跳轉(zhuǎn),書寫麻煩,成功與否難以控制。
Alibaba的ARoute為了解決這些問題
使用
配置
compile 'com.alibaba:arouter-api:1.2.1.1'
annotationProcessor 'com.alibaba:arouter-compiler:1.1.4'
建議在Application中注冊
if (BuildConfig.DEBUG) { // 這兩行必須寫在init之前,否則這些配置在init過程中將無效
ARouter.openLog(); // 打印日志
ARouter.openDebug(); // 開啟調(diào)試模式(如果在InstantRun模式下運(yùn)行,必須開啟調(diào)試模式!線上版本需要關(guān)閉,否則有安全風(fēng)險(xiǎn))
}
ARouter.init(this); // 盡可能早,推薦在Application中初始化
頁面簡單跳轉(zhuǎn)
ARouter.getInstance().build("/study/tab").navigation();
需要跳轉(zhuǎn)的Activity配置
@Route(path = "/study/tab")
public class TabActivity extends AppCompatActivity{
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_tab);
}
}
AndroidManifest.xml不需要配置schema
<activity android:name=".TabActivity" />
跳轉(zhuǎn)并攜帶參數(shù)
ARouter.getInstance().build("/study/testargs")
.withString("key","Main")
.navigation();
去讀參數(shù)
@Route(path = "/study/testargs")
public class TestArgsActivity extends AppCompatActivity{
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test_args);
String key = getIntent().getStringExtra("key");
Toast.makeText(this, key, Toast.LENGTH_SHORT).show();
}
}
攔截器可以用來登錄啥的巴拉巴拉。。
@Interceptor(priority = 8)
public class TestInterceptor implements IInterceptor {
@Override
public void process(Postcard postcard, InterceptorCallback callback) {
Log.e("inter","msg");
callback.onContinue(postcard);
}
@Override
public void init(Context context) {
}
}
通過Uri跳轉(zhuǎn)攔截
public class SchameFilterActivity extends AppCompatActivity{
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Uri uri = getIntent().getData();
if(uri == null){
finish();
return;
}
Postcard postcard = ARouter.getInstance().build(uri);
// for (String key: uri.getQueryParameterNames()){
// postcard.withString(key, uri.getQueryParameter(key));
// }
postcard.navigation(null, new NavigationCallback() {
@Override
public void onFound(Postcard postcard) {
}
@Override
public void onLost(Postcard postcard) {
}
@Override
public void onArrival(Postcard postcard) {
}
@Override
public void onInterrupt(Postcard postcard) {
}
});
finish();
}
}
Uri跳轉(zhuǎn)參數(shù)自動讀取
@Route(path = "/study/testargs2")
public class TestArgs2Activity extends AppCompatActivity{
@Autowired
public String key;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test_args);
ARouter.getInstance().inject(this);
Toast.makeText(this, key, Toast.LENGTH_SHORT).show();
}
}
關(guān)于實(shí)現(xiàn)原理

使用Processor在編譯器讀取注解的Activity和注解的path,使用javapoet生成ARouter$$Group$$path 文件 里面保存頁面的路由信息
/**
* DO NOT EDIT THIS FILE!!! IT WAS GENERATED BY AROUTER. */
public class ARouter$$Group$$study implements IRouteGroup {
@Override
public void loadInto(Map<String, RouteMeta> atlas) {
atlas.put("/study/tab", RouteMeta.build(RouteType.ACTIVITY, TabActivity.class, "/study/tab", "study", null, -1, -2147483648));
atlas.put("/study/testargs", RouteMeta.build(RouteType.ACTIVITY, TestArgsActivity.class, "/study/testargs", "study", null, -1, -2147483648));
atlas.put("/study/testargs2", RouteMeta.build(RouteType.ACTIVITY, TestArgs2Activity.class, "/study/testargs2", "study", new java.util.HashMap<String, Integer>(){{put("key", 8); }}, -1, -2147483648));
}
}
在頁面第一次跳轉(zhuǎn)的時候,將路由信息讀取到Warehouse的routes,在尋找路由進(jìn)行跳轉(zhuǎn)。
關(guān)于編譯時生成代碼 請參考 編譯時生成代碼