中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當(dāng)前位置: 首頁 > news >正文

西峰住房和城鄉(xiāng)建設(shè)局網(wǎng)站怎么建網(wǎng)站平臺賣東西

西峰住房和城鄉(xiāng)建設(shè)局網(wǎng)站,怎么建網(wǎng)站平臺賣東西,深圳網(wǎng)站建設(shè)網(wǎng)絡(luò)推廣,推廣軟文平臺一、簡介 眾所周知,在日常開發(fā)中,隨著項目業(yè)務(wù)越來越復(fù)雜,項目中的代碼量也越來越多,如果維護、擴展、解耦等成了一個非常頭疼問題,隨之孕育而生的諸如插件化、組件化、模塊化等熱門技術(shù)。 而其中組件化中一項的難點&…

一、簡介

眾所周知,在日常開發(fā)中,隨著項目業(yè)務(wù)越來越復(fù)雜,項目中的代碼量也越來越多,如果維護、擴展、解耦等成了一個非常頭疼問題,隨之孕育而生的諸如插件化、組件化、模塊化等熱門技術(shù)。 而其中組件化中一項的難點,就是實現(xiàn)各個組件之間的通訊,我們通常解決方案采用路由中間件,來實現(xiàn)頁面之間跳轉(zhuǎn)關(guān)系。 ARouter 是阿里開源路由框架,常被用于組件之間、模塊之間的跳轉(zhuǎn),由于是國人團隊開發(fā)的,所以你懂的,中文文檔非常詳細。

二、入門

2.1.添加依賴

android {defaultConfig {...javaCompileOptions {annotationProcessorOptions {arguments = [AROUTER_MODULE_NAME: project.getName()]}}}
}dependencies {api'com.alibaba:arouter-api:1.5.0'annotationProcessor 'com.alibaba:arouter-compiler:1.2.2'
}

2.2.初始化

在 Application 中初始化

if (BuildConfig.DEBUG) {ARouter.openLog()     // 打印日志ARouter.openDebug()   // 開啟調(diào)試模式(如果在InstantRun模式下運行,必須開啟調(diào)試模式!線上版本需要關(guān)閉,否則有安全風(fēng)險)
}
ARouter.init(this);

2.3.添加注解

@Route(path = "/main/main_main")
public class MainActivity extend BaseActivity {...
}

2.4.發(fā)起路由

// 1.應(yīng)用內(nèi)簡單的跳轉(zhuǎn)(通過URL跳轉(zhuǎn)在'進階用法'中)
ARouter.getInstance().build("/main/main_main").navigation();// 2.跳轉(zhuǎn)并攜帶參數(shù)
ARouter.getInstance().build("/main/main_main").withLong("id", 10086L).withString("name", "Test").navigation();

三、原理解析

在原理解析之前,我們先了解 ARouter 使用關(guān)鍵技術(shù)-APT(Annotation Processing Tool),它是 javac 的一個工具,中文譯名為編譯時注解處理器,說白了,APT 用來編譯時,掃描和處理注解,獲取注解和被注解類等相關(guān)信息,拿到這些信息之后,自動生成一些代碼,核心是 AbstractProcessor 這個類,APT 運用非常廣泛,諸如 ButterKnife、EventBus、Dagger2 等使用運用到了 APT,ARouter 也不例外。運用 APT 技術(shù)我們可以自己寫一些注解處理器,例如處理網(wǎng)絡(luò)、打印出錯信息等。

3.1 分析

我們來看看 ARouter 初始化

//1.初始化
ARouter.init(application)//2.ARouter#init
public static void init(Application application) {if (!hasInit) {logger = _ARouter.logger;_ARouter.logger.info(Consts.TAG, "ARouter init start.");//委托給_ARouter去初始化hasInit = _ARouter.init(application);if (hasInit) {_ARouter.afterInit();}//初始化之后調(diào)用afterInit_ARouter.logger.info(Consts.TAG, "ARouter init over.");}}

從上面我們可以看到 ARouter 采用門面模式,實際上委托給 *ARouter 處理,*ARouter 是整個框架的路由中心控制器,負責(zé)處理控制整個路由的流程。接下來,我們看看 _ARouter 初始化化。

protected static synchronized boolean init(Application application) {mContext = application;//調(diào)用 LogisticsCenter 的初始化LogisticsCenter.init(mContext, executor);logger.info(Consts.TAG, "ARouter init success!");hasInit = true;mHandler = new Handler(Looper.getMainLooper());return true;
}//LogisticsCenter#init
public synchronized static void init(Context context, ThreadPoolExecutor tpe) throws HandlerException {mContext = context;executor = tpe;try {long startInit = System.currentTimeMillis();loadRouterMap();if (registerByPlugin) {logger.info(TAG, "Load router map by arouter-auto-register plugin.");} else {Set<String> routerMap;//1.如果是debug模式,或者有更新if (ARouter.debuggable() || PackageUtils.isNewVersion(context)) {logger.info(TAG, "Run with debug mode or new install, rebuild router map.");//1.掃描包,獲取ROUTE_ROOT_PAKCAGE(com.alibaba.android.arouter.routes)包下的類routerMap = ClassUtils.getFileNameByPackageName(mContext, ROUTE_ROOT_PAKCAGE);if (!routerMap.isEmpty()) {context.getSharedPreferences(AROUTER_SP_CACHE_KEY, Context.MODE_PRIVATE).edit().putStringSet(AROUTER_SP_KEY_MAP, routerMap).apply();}PackageUtils.updateVersion(context);    // Save new version name when router map update finishes.} else {logger.info(TAG, "Load router map from cache.");//2.獲取本地緩存routerMap = new HashSet<>(context.getSharedPreferences(AROUTER_SP_CACHE_KEY, Context.MODE_PRIVATE).getStringSet(AROUTER_SP_KEY_MAP, new HashSet<String>()));}logger.info(TAG, "Find router map finished, map size = " + routerMap.size() + ", cost " + (System.currentTimeMillis() - startInit) + " ms.");startInit = System.currentTimeMillis();for (String className : routerMap) {//3.將 IRouteRoot,IRouteGroup和IProviderGroup的實現(xiàn)類,//通過注解生成,并且加載 Warehouse(數(shù)據(jù)倉庫)// Warehouse:數(shù)據(jù)倉庫,存儲路由配置信息和具體生成的IProvider對象if (className.startsWith(ROUTE_ROOT_PAKCAGE + DOT + SDK_NAME + SEPARATOR + SUFFIX_ROOT)) {//1.加載 IRouteRoot,每個moudle下都會生成一個該類型的實現(xiàn)類,//通過module名來區(qū)分的,作用是將每個module下所有的分組按照組名//和對應(yīng)分組的實現(xiàn)類(IRouteGroup接口的實現(xiàn)類)的 Class 對象做一個映射,//然后保存在一個全局的 groupIndex 的 map 表中。((IRouteRoot) (Class.forName(className).getConstructor().newInstance())).loadInto(Warehouse.groupsIndex);} else if (className.startsWith(ROUTE_ROOT_PAKCAGE + DOT + SDK_NAME + SEPARATOR + SUFFIX_INTERCEPTORS)) {//2.加載 IInterceptorGroup 作用是將各個module下的  自定義的i nterceptor 按照優(yōu)先級和 interceptor的       // Class 對象做一個映射,然后保存在一個全局的 interceptorIndex 的 map 表中。((IInterceptorGroup) (Class.forName(className).getConstructor().newInstance())).loadInto(Warehouse.interceptorsIndex);} else if (className.startsWith(ROUTE_ROOT_PAKCAGE + DOT + SDK_NAME + SEPARATOR + SUFFIX_PROVIDERS)) {//3.加載 IProviderGroup 該類的作用的是將項目中自定義的提供序//列化功能的類的相關(guān)信息以RouteMeta 類的對象保存在全局的providerIndex的map表中((IProviderGroup) (Class.forName(className).getConstructor().newInstance())).loadInto(Warehouse.providersIndex);}}}logger.info(TAG, "Load root element finished, cost " + (System.currentTimeMillis() - startInit) + " ms.");if (Warehouse.groupsIndex.size() == 0) {logger.error(TAG, "No mapping files were found, check your configuration please!");}if (ARouter.debuggable()) {logger.debug(TAG, String.format(Locale.getDefault(), "LogisticsCenter has already been loaded, GroupIndex[%d], InterceptorIndex[%d], ProviderIndex[%d]", Warehouse.groupsIndex.size(), Warehouse.interceptorsIndex.size(), Warehouse.providersIndex.size()));}} catch (Exception e) {throw new HandlerException(TAG + "ARouter init logistics center exception! [" + e.getMessage() + "]");}}

從上面代碼我們可以看到調(diào)用 LogisticsCenter,后勤中心主要完成兩件事

  • 獲取到 com.alibaba.android.arouter.routes 包下的所有 class 文件類名

  • 根據(jù)找到的類名去加載相關(guān)的實例到Warehouse中,com.alibaba.android.arouter.routes 包下面的 class 是注解解析器自動生成,主要 IRouteRoot,IRouteGroup 和 IProviderGroup 的實現(xiàn)類,當(dāng)我們使用 @Route 注解某個類時,會將這個類的信息注入的到自動生成的上述實現(xiàn)類中。 接下來調(diào)用 afterInit()。

//_ARouter#afterInit
static void afterInit() {// 調(diào)用 Postcard#build 方法,獲取 InterceptorService 攔截服務(wù)控制器interceptorService = (InterceptorService) ARouter.getInstance().build("/arouter/service/interceptor").navigation();}//build 方法實際上,將 path 和 group 信息封裝到 Postcard,生成一個要跳轉(zhuǎn)的信息表protected Postcard build(String path) {if (TextUtils.isEmpty(path)) {throw new HandlerException(Consts.TAG + "Parameter is invalid!");} else {//生成具體實例PathReplaceService pService = ARouter.getInstance().navigation(PathReplaceService.class);if (null != pService) {path = pService.forString(path);}return build(path, extractGroup(path));}}//Postcard#navigation 這個方法實現(xiàn)了跳轉(zhuǎn),我們點進去會發(fā)現(xiàn),最后調(diào)用 _ARouter#navigation
//_ARouter#navigation
protected Object navigation(final Context context, final Postcard postcard, final int requestCode, final NavigationCallback callback) {PretreatmentService pretreatmentService = ARouter.getInstance().navigation(PretreatmentService.class);if (null != pretreatmentService && !pretreatmentService.onPretreatment(context, postcard)) {// Pretreatment failed, navigation canceled.return null;}try {//1.調(diào)用 LogisticsCenter#completion 的方法LogisticsCenter.completion(postcard);......//不是綠色通道,通過攔截控制器依次調(diào)用不同攔截器處理信息  if (!postcard.isGreenChannel()) {  //每個攔截器的攔截方法調(diào)用都是在子線程中執(zhí)行的interceptorService.doInterceptions(postcard, new InterceptorCallback() {@Overridepublic void onContinue(Postcard postcard) {_navigation(context, postcard, requestCode, callback);}@Overridepublic void onInterrupt(Throwable exception) {if (null != callback) {//只要有一個攔截器攔截該包裹,則回調(diào)onInterrupt方法宣告本次路由被終止callback.onInterrupt(postcard);}}});} else {//2.如果是綠色通道,調(diào)用_navigation方法進行具體的導(dǎo)航return _navigation(context, postcard, requestCode, callback);}return null;}   }//LogisticsCenter#completion
public synchronized static void completion(Postcard postcard) {......//1.Warehouse.routes獲取RouteMeta,RouteMeta 路由信息描述類,存儲目標(biāo)地址的類型,路徑,參數(shù)等信RouteMeta routeMeta = Warehouse.routes.get(postcard.getPath());if (null == routeMeta) {   //如果沒有路由信息,則嘗試去數(shù)據(jù)倉庫查找Class<? extends IRouteGroup> groupMeta = Warehouse.groupsIndex.get(postcard.getGroup());  if (null == groupMeta) {throw new NoRouteFoundException(TAG + "There is no route match the path [" + postcard.getPath() + "], in group [" + postcard.getGroup() + "]");} else {// Load route and cache it into memory, then delete from metas.try {if (ARouter.debuggable()) {logger.debug(TAG, String.format(Locale.getDefault(), "The group [%s] starts loading, trigger by [%s]", postcard.getGroup(), postcard.getPath()));}IRouteGroup iGroupInstance = groupMeta.getConstructor().newInstance();iGroupInstance.loadInto(Warehouse.routes);Warehouse.groupsIndex.remove(postcard.getGroup());if (ARouter.debuggable()) {logger.debug(TAG, String.format(Locale.getDefault(), "The group [%s] has already been loaded, trigger by [%s]", postcard.getGroup(), postcard.getPath()));}} catch (Exception e) {throw new HandlerException(TAG + "Fatal exception when loading group meta. [" + e.getMessage() + "]");}completion(postcard);   // Reload}  else {//找到路由信息后,則將配置的路由信息填充到Postcard對象中postcard.setDestination(routeMeta.getDestination());//要跳轉(zhuǎn) Activity.class 路徑postcard.setType(routeMeta.getType());postcard.setPriority(routeMeta.getPriority());postcard.setExtra(routeMeta.getExtra());Uri rawUri = postcard.getUri();if (null != rawUri) {   //這里主要是完成參數(shù)的填充}//針對不同的路由類型進行處理switch (routeMeta.getType()) {case PROVIDER:  //如果是服務(wù)提供者,則嘗試獲取其具體實例,如果沒有,則根據(jù)路由信息構(gòu)造一個實例,初始化并存儲到數(shù)據(jù)倉庫,Class<? extends IProvider> providerMeta = (Class<? extends IProvider>) routeMeta.getDestination();IProvider instance = Warehouse.providers.get(providerMeta);if (null == instance) { // There's no instance of this providerIProvider provider;provider = providerMeta.getConstructor().newInstance();provider.init(mContext);Warehouse.providers.put(providerMeta, provider);instance = provider;}postcard.setProvider(instance);//服務(wù)提供者被設(shè)置成綠色渠道,不用接受攔截檢查postcard.greenChannel();   break;case FRAGMENT://fragment也不用攔截檢查postcard.greenChannel();  default:break;}}//_ARouter#_navigation
//根據(jù)不同類型,路由處理和導(dǎo)航也不一樣
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()) {//是 ACTIVITY 數(shù)據(jù)填充到intent,并且調(diào)用 startActivitycase ACTIVITY:final Intent intent = new Intent(currentContext, postcard.getDestination());intent.putExtras(postcard.getExtras());// Set flags.int flags = postcard.getFlags();if (-1 != flags) {intent.setFlags(flags);} else if (!(currentContext instanceof Activity)) {    // Non activity, need less one flag.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);}// Set ActionsString action = postcard.getAction();if (!TextUtils.isEmpty(action)) {intent.setAction(action);}// Navigation in main looper.runInMainThread(new Runnable() {@Overridepublic void run() {startActivity(requestCode, currentContext, intent, postcard, callback);}});break;//PROVIDER類型,則直接返回其服務(wù)提供者case PROVIDER:return postcard.getProvider();//如果是BOARDCAST 、 CONTENT_PROVIDER 、 FRAGMENT,則創(chuàng)建其需要的實體,并填充數(shù)據(jù),返回對象   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;}

上面的初始化代碼其實就可以了解其原理,下面我們可以畫出時序圖,了解大致流程。

四、總結(jié)

ARouter 通過 apt 技術(shù),生成保存路徑(路由path)被注解(@Router)的組件類的映射關(guān)系的類,利用這些保存了映射關(guān)系的類,根據(jù)用戶的請求 postcard(明信片)尋找到要跳轉(zhuǎn)的目標(biāo)地址(class),使用 Intent 跳轉(zhuǎn)。

ARouter的重要性主要體現(xiàn)在以下幾個方面:

  1. 模塊化開發(fā):隨著軟件規(guī)模和復(fù)雜度的增加,越來越多的應(yīng)用程序采用模塊化開發(fā)方式。ARouter支持跨模塊的調(diào)用,簡化了模塊間跳轉(zhuǎn)的復(fù)雜度,降低了耦合性,提升了整個應(yīng)用的可維護性和可擴展性。
  2. 代碼解耦:在傳統(tǒng)的Activity跳轉(zhuǎn)方式中,一般是通過Intent來傳遞參數(shù),不同頁面之間的參數(shù)傳遞比較麻煩,還有可能導(dǎo)致代碼冗余。ARouter采用注解方式傳遞參數(shù),簡化了代碼的編寫和閱讀。
  3. 動態(tài)路由:路由是基于注解方式實現(xiàn)的,可以在代碼中動態(tài)注冊和刪除路由。ARouter還支持路由重定向、降級等高級功能,可以根據(jù)不同的業(yè)務(wù)場景靈活處理路由邏輯。
  4. 統(tǒng)一管理:ARouter提供了統(tǒng)一管理路由配置的界面,可以直覽整個項目的路由規(guī)則,方便開發(fā)人員進行維護和管理。

ARouter是一款非常實用的路由框架,可以幫助開發(fā)者在模塊化開發(fā)、代碼解耦、動態(tài)路由和統(tǒng)一管理等方面提高開發(fā)效率和應(yīng)用質(zhì)量。

下面整理了《Android 架構(gòu)學(xué)習(xí)手冊》+《深入理解Gradle框架》學(xué)習(xí)筆記,根據(jù)自己學(xué)習(xí)中所做的一些筆錄來整的,主要也是方便后續(xù)好復(fù)習(xí)翻閱,省掉在去網(wǎng)上查找的時間,以免在度踩坑,如果大家有需要的可以直接 通過點擊此處↓↓↓ 進行參考學(xué)習(xí):https://qr21.cn/CaZQLo?BIZ=ECOMMERCE

Android 架構(gòu)學(xué)習(xí)手冊

?

?

深入理解Gradle框架

http://www.risenshineclean.com/news/47362.html

相關(guān)文章:

  • 門戶網(wǎng)站開發(fā)過程百度霸屏推廣多少錢一個月
  • 網(wǎng)站制作推廣公司怎么優(yōu)化標(biāo)題和關(guān)鍵詞排名
  • 沈陽網(wǎng)站建設(shè)seo優(yōu)化站內(nèi)關(guān)鍵詞排名軟件
  • 漯河做網(wǎng)站公司關(guān)鍵詞網(wǎng)站
  • 網(wǎng)站模版 免費下載企業(yè)網(wǎng)絡(luò)營銷系統(tǒng)分析報告
  • wordpress外貿(mào)教程網(wǎng)站推廣和優(yōu)化的原因
  • 做投票網(wǎng)站全網(wǎng)搜索引擎優(yōu)化
  • 聊城哪兒做網(wǎng)站便宜沈陽沈河seo網(wǎng)站排名優(yōu)化
  • 海外 推廣網(wǎng)站高級seo是什么職位
  • 紀檢網(wǎng)站建設(shè)動態(tài)主題百度一下 你知道首頁
  • 廣州網(wǎng)站建設(shè)推廣公司上海網(wǎng)站建設(shè)公司
  • php做的網(wǎng)站如何盈利重慶seo按天收費
  • 深圳網(wǎng)站開發(fā)學(xué)習(xí)日本積分榜最新排名
  • 在哪些網(wǎng)站上申請做廣告可以在百度引擎能收到關(guān)鍵字seo網(wǎng)站推廣是什么
  • 網(wǎng)站每年多少錢怎么推廣游戲代理賺錢
  • 新聞網(wǎng)站職業(yè)技能培訓(xùn)有哪些
  • 手機網(wǎng)站后臺源碼百度店鋪怎么開通
  • 微網(wǎng)站建設(shè)訊息百度產(chǎn)品大全入口
  • 做費網(wǎng)站營銷網(wǎng)站定制
  • 北京康迪建設(shè)監(jiān)理咨詢有限公司網(wǎng)站南京seo顧問
  • 濰坊網(wǎng)站建設(shè)哪家好外貿(mào)平臺排名
  • 找人代做網(wǎng)站需要注意什么簡述常用的網(wǎng)絡(luò)營銷方法
  • 如何做網(wǎng)站地圖百度官網(wǎng)首頁官網(wǎng)
  • 網(wǎng)站支付寶怎么做的營銷和銷售的區(qū)別在哪里
  • 佛山市品牌網(wǎng)站建設(shè)哪家好網(wǎng)站建設(shè)與營銷經(jīng)驗
  • 新開傳奇網(wǎng)站3000ok推廣游戲賺錢的平臺
  • 陜西做網(wǎng)站社會化媒體營銷
  • 深圳網(wǎng)站建設(shè)sumaart精準(zhǔn)粉絲引流推廣
  • eclipse做網(wǎng)站表格百度競價推廣教程
  • 個人頁網(wǎng)址seo研究中心教程