請參考ARouter源碼淺析android
經過依賴注入的方式咱們能夠像上一篇文章中獲取跳轉參數同樣獲取服務,具體的實現咱們仍是經過源碼來看一下吧。 當咱們隊一個自定義的service標註上@Autowired註解的時候,從新編譯之後,APT會爲咱們自動生成以下代碼: bash
private Object _navigation(final Context context, final Postcard postcard, final int requestCode, final NavigationCallback callback) {
final Context currentContext = null == context ? mContext : context;
switch (postcard.getType()) {
case ACTIVITY:
……
break;
case PROVIDER:
//注意這行代碼
return postcard.getProvider();
case BOARDCAST:
case CONTENT_PROVIDER:
case FRAGMENT:
Class fragmentMeta = postcard.getDestination();
try {
Object instance = fragmentMeta.getConstructor().newInstance();
if (instance instanceof Fragment) {
((Fragment) instance).setArguments(postcard.getExtras());
} else if (instance instanceof android.support.v4.app.Fragment) {
((android.support.v4.app.Fragment) instance).setArguments(postcard.getExtras());
}
return instance;
} catch (Exception ex) {
logger.error(Consts.TAG, "Fetch fragment instance error, " + TextUtils.formatStackTrace(ex.getStackTrace()));
}
case METHOD:
case SERVICE:
default:
return null;
}
return null;
}
複製代碼
最後會根據postcard.getType()類型來匹配PROVIDER,而後返回provider實例,而provider的set是在LogisticsCenter#completion中: app
WHY:那爲何根據type和根據那麼來獲取實例會有區別呢?經過源碼咱們發現type是從providersIndex Map中去獲取實例的,而name是從providers Map中去獲取實例的。框架
相信到這你們應該已經明白了吧。 ide
咱們在實現攔截器的時候須要實現IInterceptor,而IInterceptor也實現了IProvider,因此IInterceptor也是一個服務。因此interceptor的實例獲取方式也是跟普通的service是同樣的,這裏不作分析。 post
InterceptorServiceImpl屬於arouter核心服務類 ui
一、TreeMap如不指定排序器,默認將按照key值進行升序排序,若是指定了排序器,則按照指定的排序器進行排序。 二、具體的排序規則,開發人員能夠在int compare()方法中進行指定。spa
咱們知道使用系統自帶的StartActivity()啓動後就沒法插手其中任何環節了,只能交給系統管理,這就致使了在跳轉失敗的狀況下沒法降級,而是會直接拋出運營級的異常,甚至致使崩潰,這個給用戶的感受就不是很好。因此ARouter就爲咱們提供了降級策略,主要分爲2中方式,單獨降級和全局降級(demo中這樣稱呼的)。插件
以下代碼所示: 設計
主要回調的就是onLost,那它又是在何時才被調用的呢?咱們看以下代碼
public synchronized static void completion(Postcard postcard) {
if (null == postcard) {
throw new NoRouteFoundException(TAG + "No postcard!");
}
RouteMeta routeMeta = Warehouse.routes.get(postcard.getPath());
if (null == routeMeta) { // Maybe its does't exist, or didn't load.
Class<? extends IRouteGroup> groupMeta = Warehouse.groupsIndex.get(postcard.getGroup()); // Load route meta.
if (null == groupMeta) {
throw new NoRouteFoundException(TAG + "There is no route match the path [" + postcard.getPath() + "], in group [" + postcard.getGroup() + "]");
}
}
}
複製代碼
#總結 通過兩篇文章,咱們基本上已經把ARouter的主要功能都分析了。其實看着很神奇的功能,只要咱們深刻到源碼裏就會發現其實也就那麼回事。不過咱們仍是能從優秀獲得框架中學到不少優秀的設計思想和前沿的技術的,好比IOC、APT, AOP等。