国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 開發(fā) > 綜合 > 正文

用Kotlin打造一個Router的示例代碼

2024-07-21 23:03:45
字體:
供稿:網(wǎng)友

0.

最近接收了從前的項目,之前的代碼比較凌亂,準(zhǔn)備重構(gòu)。整個項目其實功能比較明顯,而且產(chǎn)品還想給他打造成比較成熟牛逼的app,那么組件化開發(fā)勢在必行。眾所周知,模塊開發(fā),路由先行,就有了這篇文章。自從用了Kotlin后,感覺Java那些繁瑣的語法和喋喋不休的空指針判斷讓人惡心,于是決定用Kotlin來寫一個Router

1.

項目地址Router

代碼,想好再寫,首先分析一下為什么需要模塊化開發(fā),為什么路由并且這個路由需要什么功能。

1.1

為什么使用模塊化開發(fā):隨著項目的越來越大,如果把所有功能都放到一個module里,對開發(fā)和測試來說都有一個效率問題,對開發(fā)來講,由于各種業(yè)務(wù)代碼混合在一起,出現(xiàn)問題不好定位,對測試來講,每次修改都要重新編譯整個項目測試。采用組件化開發(fā),講業(yè)務(wù)模塊分到一個一個module里,彼此間相互獨立,這樣既容易定位問題,也方便測試人員進行測試,因為只需要測試相應(yīng)的module即可。所以我們的項目結(jié)構(gòu)應(yīng)該是這樣的

Kotlin,Router

1.2

為什么使用路由:上面說了,每個module是彼此獨立的,而要實現(xiàn)activity的跳轉(zhuǎn)就需要彼此引用,這是我們不想看到的,模塊間應(yīng)該是沒有依賴的,那么如何實現(xiàn)不同模塊的跳轉(zhuǎn)呢?就需要路由了。

1.3

這個路由需要什么功能:目前所需要的就是根據(jù)url實現(xiàn)不同模塊之間的Activity跳轉(zhuǎn),包括傳遞參數(shù),類似startActivity和startActivityForResult,得到不同模塊的fragment。

2.

需求想好了,該想怎么實現(xiàn)了。activity跳轉(zhuǎn)有兩種,隱式調(diào)用和顯示調(diào)用,如果采取隱式調(diào)用就要為每個activity注冊intent-filter,麻煩,那就只能顯示調(diào)用了,但是顯示調(diào)用是需要class對象的,不同module是不能得到class對象的,這怎么搞?編譯前得不到,運行時總行吧,所以我們需要一個容器來存儲不同moudle里的class對象,并且能通過一個值來進行區(qū)分,所以我們需要一個map,而值就是用來區(qū)分各個activity和fragment的url。

第二個問題來了,url如何確定,class對象怎么得到,又怎么放進map里。這里我們采用注解來做,我們用在注解里聲明了url,同時自定義Processor,在編譯時生成java文件,里面只有一個方法

public void putRouteClass(ArrayMap<String, Class<?>> routableMap) {routableMap.put("test", MainActivity.class);}

根據(jù)講每個module里添加注解的Activity和fragment的class對象放入傳入的map里。之后再Application的onCreate方法里,調(diào)用Router的register方法

fun register(vararg moduleNames: String)  {    for (moduleName in moduleNames)    {      try      {        val cla = Class.forName(Constants.PACKAGE_NAME + Constants.DOT + moduleName + "_" + Constants.ROUTER_TABLE_IMP)        val routerTable = cla.newInstance() as RouterTable        routerTable.putRouteClass(classMap)      } catch (e: ClassNotFoundException)      {        e.printStackTrace()      } catch (e: Exception)      {        e.printStackTrace()      }    }  }

這個方法很簡單,調(diào)用每個module里利用Processor生成的對象的putRouteClass方法,將Router里的一個全局map傳入,這樣,這個map就持有了所有添加注解的Activity和fragment的url以及對應(yīng)的class對象。有了class對象,那想怎么搞就怎么搞了

//類似startActivityfun go(context: Context, url: String, extras: Bundle? = null)  {    val intent = Intent(context, classMap[url])    if (extras != null)    {      intent.putExtras(extras)    }    context.startActivity(intent)  }  fun go(fragment: Fragment,url: String, extras: Bundle? = null)  {    val context=fragment.context    if(context!=null)    {      go(context, url, extras)    }  }  //類似startActivityForResult  fun goForResult(context: Context, url: String, requestCode: Int, extras: Bundle? = null)  {    val intent = Intent(context, classMap[url])    if (extras != null)    {      intent.putExtras(extras)    }    if (context is Activity)    {      context.startActivityForResult(intent, requestCode)    } else if (context is Fragment)    {      context.startActivityForResult(intent, requestCode)    }  } //得到fragment  fun getFragment(url: String): Fragment?  {    try    {      val cla = classMap[url]      if (cla != null)      {        return cla.newInstance() as Fragment      } else      {      }    } catch (e: ClassNotFoundException)    {      e.printStackTrace()    } catch (e: Exception)    {      e.printStackTrace()    }    return null  }

3.有些坑:

3.1

注冊注解解釋器的時候,不要使用google的autoservice庫了,采用resoureces,META-INF,不然沒效果。別問為什么,我也不知道

3.2

在gradle文件里使用注解解釋器使用kapt代替annoationProcessor

apply plugin: 'kotlin-kapt'dependencies {kapt project(':processor')api project(':router')}

3.3

生成的java文件在每個module的build/generated/source/kapt里

4.

其實在上家公司的時候就打算寫一個路由,只是由于種種原因最近沒能成型,這里只是給大家提供一種思路,作為思路文,就不在普及注解和編譯時注解解釋器了,請自行查詢資料。

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持VeVb武林網(wǎng)。


注:相關(guān)教程知識閱讀請移步到kotlin教程頻道。
發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 濮阳县| 阳曲县| 漳州市| 固镇县| 建阳市| 民权县| 定兴县| 曲靖市| 嘉黎县| 财经| 临澧县| 东宁县| 丹东市| 盐源县| 宿州市| 双牌县| 会宁县| 阿荣旗| 贺兰县| 鹤山市| 石渠县| 吉安县| 金溪县| 迁西县| 福清市| 阿勒泰市| 黄大仙区| 娄烦县| 乾安县| 新乐市| 平南县| 沽源县| 泰安市| 游戏| 原平市| 开原市| 环江| 濮阳市| 新干县| 衢州市| 崇阳县|