Android組件化工具ARouter使用方法詳細分析
前言
組件,就是對數據和方法的簡單封裝,功能單一,高類聚,是業務劃分的最小粒度。組件化是基於可重用的目的,將大型軟件系統按照分離關註點的形式,拆分成多個獨立組件,使得整個軟件是單個或多個組件元件組裝起來。那組件之間如何通信呢?這就得益於ARouter。
Android原生的路由方案是Intent的顯式和隱式跳轉,顯式需要對目標的引用,會導致不同頁面的耦合,隱式集中配置在manifest中,不利於維護和管理。況且,在組件化開發中,各模塊之間無法直接引用,那麼,ARouter路由框架就派上用場瞭。
一個用於幫助 Android App 進行組件化改造的框架 —— 支持模塊間的路由、通信、解耦
原理簡述
ARouter通過APT技術,生成保存路徑(路由path)和被註解(@Router)的組件類的映射關系的類,利用這些保存瞭映射關系的類,根據用戶的請求postcard尋找到要跳轉的目標地址,使用Intent跳轉。所以,該框架的核心是利用APT生成的映射關系,APT的作用是在編譯階段掃描並處理代碼中的註解,然後根據註解輸出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'
引入後需要註意的一點是:要在gradle.properties文件中加入下面這個,不然會編譯不過去,這也是我遇到的一個小坑。
android.enableJetifier=true
在Application中初始化
if (isDebug()) { ARouter.openLog() //打印日志 ARouter.openDebug() //開啟調試模式,線上需關閉 } ARouter.init(this)
在支持路由的頁面上添加如下的註解,路徑至少需要兩級
@Route(path = "/home/HomeActivity") class HomeActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_home) } }
然後在另一個Activity中,進行跳轉
ARouter.getInstance().build("/home/HomeActivity").navigation()
如果需要傳遞參數的話,可以這樣做
ARouter.getInstance().build("/home/HomeActivity") .withString("name", "Uncle Xing") .withInt("age", 25) .withSerializable("user", User("Uncle Xing", 25)) .navigation()
然後在目標Activity中通過Autowired接收,ARouter會自動對字段進行賦值,無需主動獲取
@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() } }
在組件化開發中,我們通常會有一些公共Module來作為共有功能,那這個時候就可以使用ARouter的依賴註入解耦,組件件的通信,首先我們要聲明接口,其他組件通過這個接口來調用方法
interface MyProvider : IProvider { fun getData(): String }
實現類
@Route(path = "/common/MyProviderImpl") class MyProviderImpl : MyProvider { override fun getData(): String { return "Welcome to my blog" } override fun init(context: Context?) { } }
其他組件的Activity就可以這樣調用
class MainActivity : AppCompatActivity() { /** * 當一個接口隻有一個實現類的時候,Autowired可以不設置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() } }
上面是使用依賴註入的方式,通過註解標註字段,即可使用,無需主動獲取,除此之外,我們也可以使用賴查找的方式,比如上面的代碼我們也可以寫成這樣
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 /** * 發現的方式有byName和byType,如果一個接口隻有一個實現的話,也可以使用byType,可以寫成 * myProvider = ARouter.getInstance().navigation(MyProvider::class.java) */ findViewById<TextView>(R.id.provider_text).text = myProvider?.getData() } }
我們也可以動態註冊路由,這樣,目標頁面和服務就可以不標註 @Route 註解。不過,一般組件化項目都不會這樣幹,適合部分插件化架構的項目或其他場景。
ARouter.getInstance().addRouteGroup { it["/home/HomeActivity"] = RouteMeta.build( RouteType.ACTIVITY, //路由信息 HomeActivity::class.java, //目標class "/home/HomeActivity", //path "home", //Group,盡量保持和path的第一段相同 0, 0 ) }
註意:同一批次僅允許相同 group 的路由信息註冊
到此這篇關於Android組件化工具ARouter使用方法詳細分析的文章就介紹到這瞭,更多相關Android ARouter內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!
推薦閱讀:
- Android使用DatePickerDialog顯示時間
- Android實現跑馬燈效果的兩種簡單方式
- Android seekbar實現可拖動進度條
- Android使用setContentView實現頁面的轉換效果
- Android實現單選按鈕