主要參考文章:
WMRouter源碼分析(1)-基本結(jié)構(gòu)分析
WMRouter 整體理解可分4步:這里寫了大致流程握侧,細節(jié)請結(jié)合代碼
1柑爸、注解部分 - 編譯時注解
2企蹭、插件源碼部分
3雳攘、初始化
4、使用
1任柜、注解部分 - 編譯時注解
基礎(chǔ)篇:帶你從頭到尾玩轉(zhuǎn)注解
利用javapoet
卒废,根據(jù)注解參數(shù),生成java文件;
UriAnnotationProcessor把有RouterUri注解的文件宙地,生成ServiceInit_eb71854fbd69455ef4e0aa026c2e9881.java, UriAnnotationInit_43645645645646456.java
public class ServiceInit_eb71854fbd69455ef4e0aa026c2e9881 {
public static void init() {
ServiceLoader.put(IUriAnnotationInit.class, "com.sankuai.waimai.router.generated.UriAnnotationInit_72565413b8384a4bebb02d352762d60d", com.sankuai.waimai.router.generated.UriAnnotationInit_72565413b8384a4bebb02d352762d60d.class, false);
}
}
public class UriAnnotationInit_72565413b8384a4bebb02d352762d60d implements IUriAnnotationInit {
public void init(UriAnnotationHandler handler) {
handler.register("", "", "/show_toast_handler", new ShowToastHandler(), false);
handler.register("", "", "/login", "com.sankuai.waimai.router.demo.advanced.account.LoginActivity", false);
handler.register("", "", "/account_with_login", "com.sankuai.waimai.router.demo.advanced.account.UserAccountActivity", false, new LoginInterceptor());
}
}
2摔认、插件源碼部分:
Gradle Transform API 的基本使用
插件源碼 遍歷jar文件
及com.sankuai.waimai.router.generated.service
目錄下 的 ServiceInit_XXXX 的文件,再使用 asm
生成下面的ServiceLoaderInit.class文件
public class ServiceLoaderInit {
public static void init() {
ServiceInit_aea7f96d0419b507d9b0ef471913b2f5.init();
ServiceInit_f3649d9f5ff15a62b844e64ca8434259.init();
ServiceInit_eb71854fbd69455ef4e0aa026c2e9881.init();
ServiceInit_b57118238b4f9112ddd862e55789c834.init();
ServiceInit_f1e07218f6691f962a9f674eb5b4b8bd.init();
ServiceInit_4268a3e74040533ba48f2e1679155468.init();
ServiceInit_e694d982fb5d7a3a8c6b7085829e74a6.init();
ServiceInit_ee5f6404731417fe1433da40fd3c9708.init();
ServiceInit_9482ef47a8cf887ff1dc4bf705d5fc0a.init();
ServiceInit_36ed390bf4b81a8381d45028b37cc645.init();
}
}
3宅粥、初始化:
// application 中初始化
Router.init(rootHandler);
new AsyncTask<Void, Void, Void>() { // 懶加載后臺初始化(可選)
@Override
protected Void doInBackground(Void... voids) {
Router.lazyInit();
return null;
}
}.execute();
//Router.java
public static void lazyInit() {
ServiceLoader.lazyInit();
getRootHandler().lazyInit();
}
ServiceLoader.lazyInit() 中 使用反射 調(diào)用 插件生成的ServiceLoaderInit.init()
参袱,加載所有服務(wù); getRootHandler().lazyInit();從前面加載的服務(wù)中查找 有關(guān)服務(wù),調(diào)用ServiceInit_XXXX的init()秽梅,繼而調(diào)用UriAnnotationInit_72565413b8384a4bebb02d352762d60d.init(UriAnnotationHandler handler)抹蚀,注冊各種handler 進 roothandler 中的各種分類handler中;
public DefaultRootUriHandler(Context context,
@Nullable String defaultScheme, @Nullable String defaultHost) {
super(context);
mPageAnnotationHandler = createPageAnnotationHandler();
mUriAnnotationHandler = createUriAnnotationHandler(defaultScheme, defaultHost);
mRegexAnnotationHandler = createRegexAnnotationHandler();
// 按優(yōu)先級排序企垦,數(shù)字越大越先執(zhí)行
// 處理RouterPage注解定義的內(nèi)部頁面跳轉(zhuǎn)环壤,如果注解沒定義,直接結(jié)束分發(fā)
addChildHandler(mPageAnnotationHandler, 300);
// 處理RouterUri注解定義的URI跳轉(zhuǎn)钞诡,如果注解沒定義郑现,繼續(xù)分發(fā)到后面的Handler
addChildHandler(mUriAnnotationHandler, 200);
// 處理RouterRegex注解定義的正則匹配
addChildHandler(mRegexAnnotationHandler, 100);
// 添加其他用戶自定義Handler...
// 都沒有處理,則嘗試使用默認的StartUriHandler直接啟動Uri
addChildHandler(new StartUriHandler(), -100);
// 全局OnCompleteListener荧降,用于輸出跳轉(zhuǎn)失敗提示信息
setGlobalOnCompleteListener(DefaultOnCompleteListener.INSTANCE);
}
2接箫、使用:
Router.startUri(uriRequest);
從roothandler 中各個分handler 中查找能處理 請求的 handler。
至于查找過程則是 遍歷+ 遞歸