【移動(dòng)應(yīng)用開發(fā)技術(shù)】ARouter的原理的使用_第1頁
【移動(dòng)應(yīng)用開發(fā)技術(shù)】ARouter的原理的使用_第2頁
【移動(dòng)應(yīng)用開發(fā)技術(shù)】ARouter的原理的使用_第3頁
【移動(dòng)應(yīng)用開發(fā)技術(shù)】ARouter的原理的使用_第4頁
【移動(dòng)應(yīng)用開發(fā)技術(shù)】ARouter的原理的使用_第5頁
已閱讀5頁,還剩19頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

【移動(dòng)應(yīng)用開發(fā)技術(shù)】ARouter的原理的使用

初始化ARouter在使用前需要通過調(diào)用Arouter.init方法并傳入Application進(jìn)行初始化:

/**

*Init,itmustbecallbeforeusedrouter.

*/

publicstaticvoidinit(Applicationapplication){

if(!hasInit){

logger=_ARouter.logger;

_AR(Consts.TAG,"ARouterinitstart.");

hasInit=_ARouter.init(application);

if(hasInit){

_ARouter.afterInit();

}

_AR(Consts.TAG,"ARouterinitover.");

}

}這里調(diào)用到了_ARouter.init,這個(gè)_ARouter類才是ARouter的核心類:

protectedstaticsynchronizedbooleaninit(Applicationapplication){

mContext=application;

LogisticsCenter.init(mContext,executor);

(Consts.TAG,"ARouterinitsuccess!");

hasInit=true;

//It'snotagoodidea.

//if(Build.VERSION.SDK_INT>Build.VERSION_CODES.ICE_CREAM_SANDWICH){

//

application.registerActivityLifecycleCallbacks(newAutowiredLifecycleCallback());

}

returntrue;

}這里實(shí)際上調(diào)用到了LogisticsCenter.init:publicsynchronizedstaticvoidinit(Contextcontext,ThreadPoolExecutortpe)throwsHandlerException{

mContext=context;

executor=tpe;

try{

longstartInit=System.currentTimeMillis();

Set<String>routerMap;

//獲取存儲(chǔ)ClassName集合的routerMap(debug模式下每次都會(huì)拿最新的)

if(ARouter.debuggable()||PackageUtils.isNewVersion(context)){

(TAG,"Runwithdebugmodeornewinstall,rebuildroutermap.");

//根據(jù)指定的packageName獲取package下的所有ClassName

routerMap=ClassUtils.getFileNameByPackageName(mContext,ROUTE_ROOT_PAKCAGE);

if(!routerMap.isEmpty()){

//存入SP緩存

context.getSharedPreferences(AROUTER_SP_CACHE_KEY,Context.MODE_PRIVATE).edit().putStringSet(AROUTER_SP_KEY_MAP,routerMap).apply();

}

}else{

(TAG,"Loadroutermapfromcache.");

//release模式下,已經(jīng)緩存了ClassName列表

routerMap=newHashSet<>(context.getSharedPreferences(AROUTER_SP_CACHE_KEY,Context.MODE_PRIVATE).getStringSet(AROUTER_SP_KEY_MAP,newHashSet<String>()));

}

(TAG,"Findroutermapfinished,mapsize="+routerMap.size()+",cost"+(System.currentTimeMillis()-startInit)+"ms.");

startInit=System.currentTimeMillis();

//遍歷ClassName

for(StringclassName:routerMap){

if(className.startsWith(ROUTE_ROOT_PAKCAGE+DOT+SDK_NAME+SEPARATOR+SUFFIX_ROOT)){

//發(fā)現(xiàn)是Root,加載類構(gòu)建對(duì)象后通過loadInto加載進(jìn)Warehouse.groupsIndex

((IRouteRoot)(Class.forName(className).getConstructor().newInstance())).loadInto(Warehouse.groupsIndex);

}elseif(className.startsWith(ROUTE_ROOT_PAKCAGE+DOT+SDK_NAME+SEPARATOR+SUFFIX_INTERCEPTORS)){

//發(fā)現(xiàn)是Interceptor,加載類構(gòu)建對(duì)象后通過loadInto加載進(jìn)WerceptorsIndex

((IInterceptorGroup)(Class.forName(className).getConstructor().newInstance())).loadInto(WerceptorsIndex);

}elseif(className.startsWith(ROUTE_ROOT_PAKCAGE+DOT+SDK_NAME+SEPARATOR+SUFFIX_PROVIDERS)){

//發(fā)現(xiàn)是ProviderGroup,加載類構(gòu)建對(duì)象后通過loadInto加載進(jìn)WvidersIndex

((IProviderGroup)(Class.forName(className).getConstructor().newInstance())).loadInto(WvidersIndex);

}

}

//...

}catch(Exceptione){

thrownewHandlerException(TAG+"ARouterinitlogisticscenterexception!["+e.getMessage()+"]");

}

}1.獲取com.alibaba.android.arouter.routes下存儲(chǔ)ClassName的集合routerMap。2.若為debug模式或之前沒有解析過routerMap,則通過ClassUtils.getFileNameByPackageName方法對(duì)指定package下的所有ClassName進(jìn)行解析并存入SP。3.若并非debug模式,并且之前已經(jīng)解析過,則直接從SP中取出。(debug每次都需要更新,因?yàn)轭悤?huì)隨著代碼的修改而變動(dòng))4.遍歷routerMap中的ClassName。如果是RouteRoot,則加載類構(gòu)建對(duì)象后通過loadInto加載進(jìn)Warehouse.groupsIndex。如果是InterceptorGroup,則加載類構(gòu)建對(duì)象后通過loadInto加載進(jìn)WerceptorsIndex。如果是ProviderGroup,則加載類構(gòu)建對(duì)象后通過loadInto加載進(jìn)WvidersIndex`。1.獲取com.alibaba.android.arouter.routes下存儲(chǔ)ClassName的集合routerMap。2.若為debug模式或之前沒有解析過routerMap,則通過ClassUtils.getFileNameByPackageName方法對(duì)指定package下的所有ClassName進(jìn)行解析并存入SP。3.若并非debug模式,并且之前已經(jīng)解析過,則直接從SP中取出。(debug每次都需要更新,因?yàn)轭悤?huì)隨著代碼的修改而變動(dòng))4.遍歷routerMap中的ClassName。我們先看看ClassUtils.getFileNameByPackageName是如何對(duì)指定package下的ClassName集合進(jìn)行解析的:

publicstaticSet<String>getFileNameByPackageName(Contextcontext,finalStringpackageName){

finalSet<String>classNames=newHashSet<>();

//通過getSourcePaths方法獲取dex文件path集合

List<String>paths=getSourcePaths(context);

//通過CountDownLatch對(duì)path的遍歷處理進(jìn)行控制

finalCountDownLatchparserCtl=newCountDownLatch(paths.size());

//遍歷path,通過DefaultPoolExecutor并發(fā)對(duì)path進(jìn)行處理

for(finalStringpath:paths){

DefaultPoolExecutor.getInstance().execute(newRunnable(){

@Override

publicvoidrun(){

//加載path對(duì)應(yīng)的dex文件

DexFiledexfile=null;

try{

if(path.endsWith(EXTRACTED_SUFFIX)){

//zip結(jié)尾通過DexFile.loadDex進(jìn)行加載

dexfile=DexFile.loadDex(path,path+".tmp",0);

}else{

//否則通過newDexFile加載

dexfile=newDexFile(path);

}

//遍歷dex中的Entry

Enumeration<String>dexEntries=dexfile.entries();

while(dexEntries.hasMoreElements()){

//如果是對(duì)應(yīng)的package下的類,則添加其className

StringclassName=dexEntries.nextElement();

if(className.startsWith(packageName)){

classNames.add(className);

}

}

}catch(Throwableignore){

Log.e("ARouter","Scanmapfileindexfilesmadeerror.",ignore);

}finally{

if(null!=dexfile){

try{

dexfile.close();

}catch(Throwableignore){

}

}

parserCtl.countDown();

}

}

});

}

//所有path處理完成后,繼續(xù)向下走

parserCtl.await();

Log.d(Consts.TAG,"Filter"+classNames.size()+"classesbypackageName<"+packageName+">");

returnclassNames;

}這里的步驟比較簡(jiǎn)單,主要是如下的步驟:1.通過getSourcePaths方法獲取dex文件的path集合。2.創(chuàng)建了一個(gè)CountDownLatch控制dex文件的并行處理,以加快速度。3.遍歷path列表,通過DefaultPoolExecutor對(duì)path并行處理。4.加載path對(duì)應(yīng)的dex文件,并對(duì)其中的Entry進(jìn)行遍歷,若發(fā)現(xiàn)了對(duì)應(yīng)package下的ClassName,將其加入結(jié)果集合。5.所有dex處理完成后,返回結(jié)果1.通過getSourcePaths方法獲取dex文件的path集合。2.創(chuàng)建了一個(gè)CountDownLatch控制dex文件的并行處理,以加快速度。3.遍歷path列表,通過DefaultPoolExecutor對(duì)path并行處理。4.加載path對(duì)應(yīng)的dex文件,并對(duì)其中的Entry進(jìn)行遍歷,若發(fā)現(xiàn)了對(duì)應(yīng)package下的ClassName,將其加入結(jié)果集合。5.所有dex處理完成后,返回結(jié)果關(guān)于getSourcePaths如何獲取到的dex集合這里就不糾結(jié)了,因?yàn)槲覀兊年P(guān)注點(diǎn)不在這里。Warehouse實(shí)際上就是倉庫的意思,它存放了ARouter自動(dòng)生成的類(RouteRoot、InterceptorGroup、ProviderGroup)的信息。我們先看看Warehouse類究竟是怎樣的:

classWarehouse{

//保存RouteGroup對(duì)應(yīng)的class以及RouteMeta

staticMap<String,Class<?extendsIRouteGroup>>groupsIndex=newHashMap<>();

staticMap<String,RouteMeta>routes=newHashMap<>();

//保存Provider以及RouteMeta

staticMap<Class,IProvider>providers=newHashMap<>();

staticMap<String,RouteMeta>providersIndex=newHashMap<>();

//保存Interceptor對(duì)應(yīng)的class以及Inteceptor

staticMap<Integer,Class<?extendsIInterceptor>>interceptorsIndex=newUniqueKeyTreeMap<>("Morethanoneinterceptorsusesamepriority[%s]");

staticList<IInterceptor>interceptors=newArrayList<>();

staticvoidclear(){

routes.clear();

groupsIndex.clear();

providers.clear();

providersIndex.clear();

interceptors.clear();

interceptorsIndex.clear();

}

}可以發(fā)現(xiàn)Warehouse就是一個(gè)純粹用來存放信息的倉庫類,它的數(shù)據(jù)的實(shí)際上是通過上面的幾個(gè)自動(dòng)生成的類在loadInto中對(duì)Warehouse主動(dòng)填入數(shù)據(jù)實(shí)現(xiàn)的。例如我們打開一個(gè)自動(dòng)生成的IRouteRoot的實(shí)現(xiàn)類:publicclassARouter$$Root$$homeworkimplementsIRouteRoot{

@Override

publicvoidloadInto(Map<String,Class<?extendsIRouteGroup>>routes){

routes.put("homework",ARouter$$Group$$homework.class);

}

}可以看到,它在groupsIndex中對(duì)這個(gè)RouteRoot中的IRouteGroup進(jìn)行了注冊(cè),也就是向groupIndex中注冊(cè)了RouteGroup對(duì)應(yīng)的IRouteGroup類。其他類也是一樣,通過自動(dòng)生成的代碼將數(shù)據(jù)填入Map或List中??梢园l(fā)現(xiàn),初始化過程主要完成了對(duì)自動(dòng)生成的路由相關(guān)類RouteRoot、Interceptor、ProviderGroup的加載,對(duì)它們通過反射構(gòu)造后將信息加載進(jìn)了Warehouse類中。下面我們看看路由的跳轉(zhuǎn)是如何實(shí)現(xiàn)的,我們先看到ARouter.build方法:publicPostcardbuild(Stringpath){

return_ARouter.getInstance().build(path);

}它轉(zhuǎn)調(diào)到了_ARouter的build方法:

protectedPostcardbuild(Stringpath){

if(TextUtils.isEmpty(path)){

thrownewHandlerException(Consts.TAG+"Parameterisinvalid!");

}else{

PathReplaceServicepService=ARouter.getInstance().navigation(PathReplaceService.class);

if(null!=pService){

path=pService.forString(path);

}

returnbuild(path,extractGroup(path));

}

}它首先通過ARouter.navigation獲取到了PathReplaceService,它需要用戶進(jìn)行實(shí)現(xiàn),若沒有實(shí)現(xiàn)會(huì)返回null,若有實(shí)現(xiàn)則調(diào)用了它的forString方法傳入了用戶的RoutePath進(jìn)行路徑的預(yù)處理。最后轉(zhuǎn)調(diào)到了build(path,group),group通過extractGroup得到:privateStringextractGroup(Stringpath){

if(TextUtils.isEmpty(path)||!path.startsWith("/")){

thrownewHandlerException(Consts.TAG+"Extractthedefaultgroupfailed,thepathmustbestartwith'/'andcontainmorethan2'/'!");

}

try{

StringdefaultGroup=path.substring(1,path.indexOf("/",1));

if(TextUtils.isEmpty(defaultGroup)){

thrownewHandlerException(Consts.TAG+"Extractthedefaultgroupfailed!There'snothingbetween2'/'!");

}else{

returndefaultGroup;

}

}catch(Exceptione){

logger.warning(Consts.TAG,"Failedtoextractdefaultgroup!"+e.getMessage());

returnnull;

}

}extractGroup實(shí)際上就是對(duì)字符串處理,取出RouteGroup的名稱部分。

protectedPostcardbuild(Stringpath,Stringgroup){

if(TextUtils.isEmpty(path)||TextUtils.isEmpty(group)){

thrownewHandlerException(Consts.TAG+"Parameterisinvalid!");

}else{

PathReplaceServicepService=ARouter.getInstance().navigation(PathReplaceService.class);

if(null!=pService){

path=pService.forString(path);

}

returnnewPostcard(path,group);

}

}build(path,group)方法同樣也會(huì)嘗試獲取到PathReplaceService并對(duì)path進(jìn)行預(yù)處理。之后通過path與group構(gòu)建了一個(gè)Postcard類:

publicPostcard(Stringpath,Stringgroup){

this(path,group,null,null);

}

publicPostcard(Stringpath,Stringgroup,Uriuri,Bundlebundle){

setPath(path);

setGroup(group);

setUri(uri);

this.mBundle=(null==bundle?newBundle():bundle);

}這里最終調(diào)用到了PostCard(path,group,uri,bundle),這里只是進(jìn)行了一些參數(shù)的設(shè)置。之后,如果我們調(diào)用withInt、withDouble等方法,就可以進(jìn)行參數(shù)的設(shè)置。例如withInt方法:

publicPostcardwithInt(@NullableStringkey,intvalue){

mBundle.putInt(key,value);

returnthis;

}它實(shí)際上就是在對(duì)Bundle中設(shè)置對(duì)應(yīng)的key、value。最后我們通過navigation即可實(shí)現(xiàn)最后的跳轉(zhuǎn):

publicObjectnavigation(){

returnnavigation(null);

}

publicObjectnavigation(Contextcontext){

returnnavigation(context,null);

}

publicObjectnavigation(Contextcontext,NavigationCallbackcallback){

returnARouter.getInstance().navigation(context,this,-1,callback);

}

publicvoidnavigation(ActivitymContext,intrequestCode){

navigation(mContext,requestCode,null);

}

publicvoidnavigation(ActivitymContext,intrequestCode,NavigationCallbackcallback){

ARouter.getInstance().navigation(mContext,this,requestCode,callback);

}通過如上的navigation可以看到,實(shí)際上它們都是最終調(diào)用到ARouter.navigation方法,在沒有傳入Context時(shí)會(huì)使用Application初始化的Context,并且可以通過NavigationCallback對(duì)navigation的過程進(jìn)行監(jiān)聽。

publicObjectnavigation(ContextmContext,Postcardpostcard,intrequestCode,NavigationCallbackcallback){

return_ARouter.getInstance().navigation(mContext,postcard,requestCode,callback);

}ARouter仍然只是將請(qǐng)求轉(zhuǎn)發(fā)到了_ARouter:

protectedObjectnavigation(finalContextcontext,finalPostcardpostcard,finalintrequestCode,finalNavigationCallbackcallback){

try{

//通過LogisticsCpletion對(duì)postcard進(jìn)行補(bǔ)全

LogisticsCpletion(postcard);

}catch(NoRouteFoundExceptionex){

//...

}

if(null!=callback){

callback.onFound(postcard);

}

//如果設(shè)置了greenChannel,會(huì)跳過所有攔截器的執(zhí)行

if(!postcard.isGreenChannel()){

//沒有跳過攔截器,對(duì)postcard的所有攔截器進(jìn)行執(zhí)行

interceptorService.doInterceptions(postcard,newInterceptorCallback(){

@Override

publicvoidonContinue(Postcardpostcard){

_navigation(context,postcard,requestCode,callback);

}

@Override

publicvoidonInterrupt(Throwableexception){

if(null!=callback){

callback.onInterrupt(postcard);

}

(Consts.TAG,"Navigationfailed,terminationbyinterceptor:"+exception.getMessage());

}

});

}else{

return_navigation(context,postcard,requestCode,callback);

}

returnnull;

}上面的代碼主要有以下步驟:1.通過LogisticsCpletion對(duì)postcard進(jìn)行補(bǔ)全。2.如果postcard沒有設(shè)置greenChannel,則對(duì)postcard的攔截器進(jìn)行執(zhí)行,執(zhí)行完成后調(diào)用_navigation方法真正實(shí)現(xiàn)跳轉(zhuǎn)。3.如果postcard設(shè)置了greenChannel,則直接跳過所有攔截器,調(diào)用_navigation方法真正實(shí)現(xiàn)跳轉(zhuǎn)。1.通過LogisticsCpletion對(duì)postcard進(jìn)行補(bǔ)全。2.如果postcard沒有設(shè)置greenChannel,則對(duì)postcard的攔截器進(jìn)行執(zhí)行,執(zhí)行完成后調(diào)用_navigation方法真正實(shí)現(xiàn)跳轉(zhuǎn)。3.如果postcard設(shè)置了greenChannel,則直接跳過所有攔截器,調(diào)用_navigation方法真正實(shí)現(xiàn)跳轉(zhuǎn)。我們看看LogisticsCpletion是如何實(shí)現(xiàn)postcard的補(bǔ)全的:

publicsynchronizedstaticvoidcompletion(Postcardpostcard){

if(null==postcard){

thrownewNoRouteFoundException(TAG+"Nopostcard!");

}

//通過Warehouse.routes.get嘗試獲取RouteMeta

RouteMetarouteMeta=Warehouse.routes.get(postcard.getPath());

if(null==routeMeta){

//若routeMeta為null,可能是并不存在,或是還沒有加載進(jìn)來

//嘗試獲取postcard的RouteGroup

Class<?extendsIRouteGroup>groupMeta=Warehouse.groupsIndex.get(postcard.getGroup());

//Loadroutemeta.

if(null==groupMeta){

thrownewNoRouteFoundException(TAG+"Thereisnoroutematchthepath["+postcard.getPath()+"],ingroup["+postcard.getGroup()+"]");

}else{

//...

//如果找到了對(duì)應(yīng)的RouteGroup,則將其加載進(jìn)來并重新調(diào)用completion進(jìn)行補(bǔ)全

IRouteGroupiGroupInstance=groupMeta.getConstructor().newInstance();

iGroupInstance.loadInto(Warehouse.routes);

Warehouse.groupsIndex.remove(postcard.getGroup());

//...

completion(postcard);

//Reload

}

}else{

//如果找到了對(duì)應(yīng)的routeMeta,將它的信息設(shè)置進(jìn)postcard中

postcard.setDestination(routeMeta.getDestination());

postcard.setType(routeMeta.getType());

postcard.setPriority(routeMeta.getPriority());

postcard.setExtra(routeMeta.getExtra());

UrirawUri=postcard.getUri();

//將uri中的參數(shù)設(shè)置進(jìn)bundle中

if(null!=rawUri){

Map<String,String>resultMap=TextUtils.splitQueryParameters(rawUri);

Map<String,Integer>paramsType=routeMeta.getParamsType();

if(MapUtils.isNotEmpty(paramsType)){

//Setvaluebyitstype,justforparamswhichannotationby@Param

for(Map.Entry<String,Integer>params:paramsType.entrySet()){

setValue(postcard,

params.getValue(),

params.getKey(),

resultMap.get(params.getKey()));

}

//Saveparamsnamewhichneedautoinject.

postcard.getExtras().putStringArray(ARouter.AUTO_INJECT,paramsType.keySet().toArray(newString[]{}));

}

//Saverawuri

postcard.withString(ARouter.RAW_URI,rawUri.toString());

}

//對(duì)于provider和fragment,進(jìn)行特殊處理

switch(routeMeta.getType()){

casePROVIDER:

//如果是一個(gè)provider,嘗試從Warehouse中查找它的類并構(gòu)造對(duì)象,然后將其設(shè)置到provider

Class<?extendsIProvider>providerMeta=(Class<?extendsIProvider>)routeMeta.getDestination();

IProviderinstance=Wviders.get(providerMeta);

if(null==instance){//There'snoinstanceofthisprovider

IProviderprovider;

try{

provider=providerMeta.getConstructor().newInstance();

provider.init(mContext);

Wviders.put(providerMeta,provider);

instance=provider;

}catch(Exceptione){

thrownewHandlerException("Initproviderfailed!"+e.getMessage());

}

}

postcard.setProvider(instance);

//provider和fragment都會(huì)跳過攔截器

postcard.greenChannel();

break;

caseFRAGMENT:

//provider和fragment都會(huì)跳過攔截器

postcard.greenChannel();

default:

break;

}

}

}這個(gè)方法主要完成了對(duì)postcard的信息與Warehouse的信息進(jìn)行結(jié)合,以補(bǔ)全postcard的信息,它的步驟如下:1.通過Warehouse.routes.get根據(jù)path嘗試獲取RouteMeta對(duì)象。2.若獲取不到RouteMeta對(duì)象,可能是不存在或是還沒有進(jìn)行加載(第一次都未加載),嘗試獲取RouteGroup調(diào)用其loadInto方法將RouteMeta加載進(jìn)Warehouse,最后調(diào)用completion重新嘗試補(bǔ)全。3.將RouteMeta的信息設(shè)置到postcard中,其中會(huì)將rawUri的參數(shù)設(shè)置進(jìn)Bundle。4.對(duì)于Provider和Fragment特殊處理,其中Provider會(huì)從Warehouse中加載并構(gòu)造它的對(duì)象,然后設(shè)置到postcard。Provider和Fragment都會(huì)跳過攔截器。1.通過Warehouse.routes.get根據(jù)path嘗試獲取RouteMeta對(duì)象。2.若獲取不到RouteMeta對(duì)象,可能是不存在或是還沒有進(jìn)行加載(第一次都未加載),嘗試獲取RouteGroup調(diào)用其loadInto方法將RouteMeta加載進(jìn)Warehouse,最后調(diào)用completion重新嘗試補(bǔ)全。3.將RouteMeta的信息設(shè)置到postcard中,其中會(huì)將rawUri的參數(shù)設(shè)置進(jìn)Bundle。4.對(duì)于Provider和Fragment特殊處理,其中Provider會(huì)從Warehouse中加載并構(gòu)造它的對(duì)象,然后設(shè)置到postcard。Provider和Fragment都會(huì)跳過攔截器。RouteGroup的loadInto仍然是自動(dòng)生成的,例如下面就是一些自動(dòng)生成的代碼:

publicvoidloadInto(Map<String,RouteMeta>atlas){

atlas.put("/homework/commit",RouteMeta.build(RouteType.ACTIVITY,HomeworkCommitActivity.class,"/homework/commit","homework",null,-1,-2147483648));

//...

}它包括了我們補(bǔ)全所需要的如Destination、Class、path等信息,在生成代碼時(shí)自動(dòng)根據(jù)注解進(jìn)行生成。我們看看navigation方法是如何實(shí)現(xiàn)的跳轉(zhuǎn):

privateObject_navigation(finalContextcontext,finalPostcardpostcard,finalintrequestCode,finalNavigationCallbackcallback){

finalContextcurrentContext=null==context?mContext:context;

switch(postcard.getType()){

caseACTIVITY:

//對(duì)Activity,構(gòu)造Intent,將參數(shù)設(shè)置進(jìn)去

finalIntentintent=newIntent(currentContext,postcard.getDestination());

intent.putExtras(postcard.getExtras());

//Setflags.

intflags=postcard.getFlags();

if(-1!=flags){

intent.setFlags(flags);

}elseif(!(currentContextinstanceofActivity)){

//Nonactivity,needlessoneflag.

intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

}

//切換到主線程,根據(jù)是否需要result調(diào)用不同的startActivity方法

newHandler(Looper.getMainLooper()).post(newRunnable(){

@Override

publicvoidrun(){

if(requestCode>0){

//Needstartforresult

ActivityCompat.startActivityForResult((Activity)currentContext,intent,requestCode,postcard.getOptionsBundle());

}else{

ActivityCompat.startActivity(currentContext,intent,postcard.getOptionsBundle());

}

if((0!=postcard.getEnterAnim()||0!=postcard.getExitAnim())&¤tContextinstanceofActivity){

//Oldversion.

((Activity)currentContext).overridePendingTransition(postcard.getEnterAnim(),postcard.getExitAnim());

}

if(null!=callback){//Navigationover.

callback.onArrival(postcard);

}

}

});

break;

casePROVIDER:

//provider直接返回對(duì)應(yīng)的provider

returnpostcard.getProvider();

caseBOARDCAST:

caseCONTENT_PROVIDER:

caseFRAGMENT:

//對(duì)于broadcast、contentprovider、fragment,構(gòu)造對(duì)象,設(shè)置參數(shù)后返回

ClassfragmentMeta=postcard.getDestination();

try{

Objectinstance=fragmentMeta.getConstructor().newInstance();

if(instanceinstanceofFragment){

((Fragment)instance).setArguments(postcard.getExtras());

}elseif(instanceinstanceofandroid.support.v4.app.Fragment){

((android.support.v4.app.Fragment)instance).setArguments(postcard.getExtras());

}

returninstance;

}catch(Exceptionex){

logger.error(Consts.TAG,"Fetchfragmentinstanceerror,"+TextUtils.formatStackTrace(ex.getStackTrace()));

}

caseMETHOD:

caseSERVICE:

default:

returnnull;

}

returnnull;

}可以發(fā)現(xiàn),它會(huì)根據(jù)postcard的type來分別處理:可以發(fā)現(xiàn)ARouter的初始化和路由跳轉(zhuǎn)的整體邏輯還是不難的,實(shí)際上就是對(duì)Activity、Fragment的調(diào)轉(zhuǎn)過程進(jìn)行了包裝。ARouter除了可以通過ARouter.getInstance().build().navigation()這樣的方式實(shí)現(xiàn)頁面跳轉(zhuǎn)之外,還可以通過ARouter.getInstance().navigation(XXService.class)這樣的方式實(shí)現(xiàn)跨越組件的服務(wù)獲取,我們看看它是如何實(shí)現(xiàn)的:

public<T>Tnavigation(Class<?extendsT>service){

return_ARouter.getInstance().navigation(service);

}仍然跳轉(zhuǎn)到了_ARouter中去實(shí)現(xiàn):

protected<T>Tnavigation(Class<?extendsT>service){

try{

Postcardpostcard=LogisticsCenter.buildProvider(service.getName());

//Compatible1.0.5compilersdk.

//Earlierversionsdidnotusethefullyqualifiednametogettheservice

if(null==postcard){

//Noservice,orthisserviceinoldversion.

postcard=LogisticsCenter.buildProvider(service.getSimpleName());

}

if(null==postcard){

returnnull;

}

LogisticsCpletion(postcard);

return(T)postcard.getProvider();

}catch(NoRouteFoundExceptionex){

logger.warning(Consts.TAG,ex.getMessage());

returnnull;

}

}這里首先通過LogisticsCenter.buildProvider傳入service.class的name構(gòu)建出了一個(gè)postcard。而在ARouter老版本中,并不是通過這樣一個(gè)完整的name來獲取Service的,而是通過simpleName,下面為了兼容老版本,在獲取不到時(shí)會(huì)嘗試用老版本的方式重新構(gòu)建一次。之后會(huì)通過LogisticsCpletion對(duì)postcard進(jìn)行補(bǔ)全,最后通過postcard.Provider獲取對(duì)應(yīng)的Provider。除了buildProvider之外,其他方法我們已經(jīng)在前面進(jìn)行過分析,就不再贅述了:

publicstaticPostcardbuildProvider(StringserviceName){

RouteMetameta=WvidersIndex.get(serviceName);

if(null==meta){

returnnull;

}else{

returnnewPostcard(meta.getPath(),meta.getGroup());

}

}這里實(shí)際上非常簡(jiǎn)單,就是通過Warehouse中已經(jīng)初始化的providersIndex根據(jù)serviceName獲取對(duì)應(yīng)的RouteMeta,之后根據(jù)RouteMeta的path和group返回對(duì)應(yīng)的Postcard通過前面的分析,可以發(fā)現(xiàn)ARouter中存在一套攔截器機(jī)制,在completion的過程中對(duì)攔截器進(jìn)行了執(zhí)行,讓我們看看它的攔截器機(jī)制的實(shí)現(xiàn)。我們先看到IInterceptor接口:

publicinterfaceIInterceptorextendsIProvider{

/**

*Theoperationofthisinterceptor.

*

*@parampostcardmeta

*@paramcallbackcb

*/

voidprocess(Postcardpostcard,InterceptorCallbackcallback);

}攔截器中主要通過process方法完成執(zhí)行過程,可以在其中對(duì)postcard進(jìn)行處理。而攔截器的執(zhí)行我們知道,是通過InterceptorServiceImpl.doInterceptions實(shí)現(xiàn)的:

if(null!=Werceptors&&Werceptors.size()>0){

checkInterceptorsInitStatus();

if(!interceptorHasInit){

callback.onInterrupt(newHandlerException("Interceptorsinitializationtakestoomuchtime."));

return;

}

LogisticsCenter.executor.execute(newRunnable(){

@Override

publicvoidrun(){

CancelableCountDownLatchinterceptorCounter=newCancelableCountDownLatch(Werceptors.size());

try{

_excute(0,interceptorCounter,postcard);

interceptorCounter.await(postcard.getTimeout(),TimeUnit.SECONDS);

if(interceptorCounter.getCount()>0){

//Cancelthenavigationthistime,ifithasn'treturnanythings.

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論