Android組件化工具ARouter使用方法詳細(xì)分析
前言
組件,就是對數(shù)據(jù)和方法的簡單封裝,功能單一,高類聚,是業(yè)務(wù)劃分的最小粒度。組件化是基于可重用的目的,將大型軟件系統(tǒng)按照分離關(guān)注點(diǎn)的形式,拆分成多個獨(dú)立組件,使得整個軟件是單個或多個組件元件組裝起來。那組件之間如何通信呢?這就得益于ARouter。
Android原生的路由方案是Intent的顯式和隱式跳轉(zhuǎn),顯式需要對目標(biāo)的引用,會導(dǎo)致不同頁面的耦合,隱式集中配置在manifest中,不利于維護(hù)和管理。況且,在組件化開發(fā)中,各模塊之間無法直接引用,那么,ARouter路由框架就派上用場了。
一個用于幫助 Android App 進(jìn)行組件化改造的框架 —— 支持模塊間的路由、通信、解耦
原理簡述
ARouter通過APT技術(shù),生成保存路徑(路由path)和被注解(@Router)的組件類的映射關(guān)系的類,利用這些保存了映射關(guān)系的類,根據(jù)用戶的請求postcard尋找到要跳轉(zhuǎn)的目標(biāo)地址,使用Intent跳轉(zhuǎn)。所以,該框架的核心是利用APT生成的映射關(guān)系,APT的作用是在編譯階段掃描并處理代碼中的注解,然后根據(jù)注解輸出Java文件。
基本使用
添加依賴和配置,注意,每個使用到ARouter的Module都要引入
plugins {
id 'com.android.library'
id 'org.jetbrains.kotlin.android'
id 'kotlin-kapt'
}
kapt {
arguments {
arg("AROUTER_MODULE_NAME", project.getName())
}
}
implementation 'com.alibaba:arouter-api:1.5.2'
kapt 'com.alibaba:arouter-compiler:1.5.2'
引入后需要注意的一點(diǎn)是:要在gradle.properties文件中加入下面這個,不然會編譯不過去,這也是我遇到的一個小坑。
android.enableJetifier=true
在Application中初始化
if (isDebug()) { ARouter.openLog() //打印日志 ARouter.openDebug() //開啟調(diào)試模式,線上需關(guān)閉 } ARouter.init(this)
在支持路由的頁面上添加如下的注解,路徑至少需要兩級
@Route(path = "/home/HomeActivity") class HomeActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_home) } }
然后在另一個Activity中,進(jìn)行跳轉(zhuǎn)
ARouter.getInstance().build("/home/HomeActivity").navigation()
如果需要傳遞參數(shù)的話,可以這樣做
ARouter.getInstance().build("/home/HomeActivity") .withString("name", "Uncle Xing") .withInt("age", 25) .withSerializable("user", User("Uncle Xing", 25)) .navigation()
然后在目標(biāo)Activity中通過Autowired接收,ARouter會自動對字段進(jìn)行賦值,無需主動獲取
@Route(path = "/home/HomeActivity") class HomeActivity : AppCompatActivity() { @JvmField @Autowired var name = "" @JvmField @Autowired var age = 0 @JvmField @Autowired var user: User? = null override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_home) initView() } private fun initView() { ARouter.getInstance().inject(this) findViewById<TextView>(R.id.name).text = name findViewById<TextView>(R.id.age).text = age.toString() findViewById<TextView>(R.id.user).text = user.toString() } }
在組件化開發(fā)中,我們通常會有一些公共Module來作為共有功能,那這個時候就可以使用ARouter的依賴注入解耦,組件件的通信,首先我們要聲明接口,其他組件通過這個接口來調(diào)用方法
interface MyProvider : IProvider { fun getData(): String }
實(shí)現(xiàn)類
@Route(path = "/common/MyProviderImpl") class MyProviderImpl : MyProvider { override fun getData(): String { return "Welcome to my blog" } override fun init(context: Context?) { } }
其他組件的Activity就可以這樣調(diào)用
class MainActivity : AppCompatActivity() { /** * 當(dāng)一個接口只有一個實(shí)現(xiàn)類的時候,Autowired可以不設(shè)置name */ @JvmField @Autowired(name = "/common/MyProviderImpl") var myProvider: MyProvider? = null override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) initView() } private fun initView() { ARouter.getInstance().inject(this) findViewById<TextView>(R.id.provider_text).text = myProvider?.getData() } }
上面是使用依賴注入的方式,通過注解標(biāo)注字段,即可使用,無需主動獲取,除此之外,我們也可以使用賴查找的方式,比如上面的代碼我們也可以寫成這樣
class MainActivity : AppCompatActivity() { var myProvider: MyProvider? = null override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) initView() } private fun initView() { // ARouter.getInstance().inject(this) 這種方式不需要這句 myProvider = ARouter.getInstance().build("/common/MyProviderImpl").navigation() as MyProvider /** * 發(fā)現(xiàn)的方式有byName和byType,如果一個接口只有一個實(shí)現(xiàn)的話,也可以使用byType,可以寫成 * myProvider = ARouter.getInstance().navigation(MyProvider::class.java) */ findViewById<TextView>(R.id.provider_text).text = myProvider?.getData() } }
我們也可以動態(tài)注冊路由,這樣,目標(biāo)頁面和服務(wù)就可以不標(biāo)注 @Route 注解。不過,一般組件化項(xiàng)目都不會這樣干,適合部分插件化架構(gòu)的項(xiàng)目或其他場景。
ARouter.getInstance().addRouteGroup { it["/home/HomeActivity"] = RouteMeta.build( RouteType.ACTIVITY, //路由信息 HomeActivity::class.java, //目標(biāo)class "/home/HomeActivity", //path "home", //Group,盡量保持和path的第一段相同 0, 0 ) }
注意:同一批次僅允許相同 group 的路由信息注冊
到此這篇關(guān)于Android組件化工具ARouter使用方法詳細(xì)分析的文章就介紹到這了,更多相關(guān)Android ARouter內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Android開發(fā)之React Navigation 導(dǎo)航欄樣式調(diào)整+底部角標(biāo)消息提示
這篇文章主要介紹了React Navigation 導(dǎo)航欄樣式調(diào)整+底部角標(biāo)消息提示的相關(guān)知識,非常不錯,具有一定的參考借鑒價值 ,需要的朋友可以參考下2019-05-05Flutter使用NetworkImage實(shí)現(xiàn)圖像顯示效果
這篇文章主要為大家介紹了如何在Flutter中使用NetworkImage實(shí)現(xiàn)圖像顯示效果,文中的示例代碼講解詳細(xì),快跟隨小編一起學(xué)習(xí)一下吧2022-04-04Android應(yīng)用啟動另外一個apk應(yīng)用的方法
這篇文章主要介紹了Android應(yīng)用啟動另外一個apk應(yīng)用的方法,涉及Android基于intent的package調(diào)用與管理技巧,需要的朋友可以參考下2016-02-02學(xué)習(xí)Android Material Design(RecyclerView代替ListView)
Android Material Design越來越流行,以前很常用的 ListView 現(xiàn)在也用RecyclerView代替了,實(shí)現(xiàn)原理還是相似的,感興趣的小伙伴們可以參考一下2016-01-01android?sharedUserId?使用知識盲點(diǎn)解析
這篇文章主要為大家介紹了android?sharedUserId使用的知識盲點(diǎn)解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-02-02Android模擬器接收UDP數(shù)據(jù)包的若干問題分析
這篇文章主要介紹了Android模擬器接收UDP數(shù)據(jù)包的若干問題,結(jié)合實(shí)例形式較為詳細(xì)的分析了Android模擬器接收UDP數(shù)據(jù)的使用方法與相關(guān)注意事項(xiàng),需要的朋友可以參考下2016-04-04Android用ActionBar高仿微信主界面的實(shí)例代碼
這篇文章主要介紹了Android用ActionBar高仿微信主界面的實(shí)例代碼,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-05-05Android FaceDetector實(shí)現(xiàn)人臉檢測功能
這篇文章主要為大家詳細(xì)介紹了Android FaceDetector實(shí)現(xiàn)人臉檢測功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2018-05-05