本文已首發微信公眾號「code小生」,大家可以搜尋關注,專注安卓技術分享。
本文說明
上篇文章已分享了路由配置、跳轉、原理、完整的效果演示gif以及原始碼,而且是多 module 專案演示的,算是路由 ARouter 的入門,還沒配置使用的可以先去看看。
本文的內容主要涉及如下兩個:
- 路由攔截器使用
- module 獨立執行
前者在我們開發中有這樣一種應用場景,預設使用者不登入可以瀏覽一部分頁面,當點選部分頁面的時候就需要先去登入,也就是跳轉到登入頁面,普通的做法是根據需求挨個去做點選事件,這就很麻煩,如果需要跳轉登入的時候傳遞引數啥的,那就改動超級大了;而路由ARouter的攔截器功能就很好的解決了這個問題,還支援自定義攔截器,使用起來很靈活。
後者的使用場景適合專案大,多人開發的情景,這樣可以各自負責一個模組,獨立除錯執行,利於專案管理以及程式碼的維護。這塊在上一篇文章的前提下還需要額外配置,本文會講。
module 獨立執行
先來看看module獨立執行,然後我們在各個模組做一個模擬的跳轉頁面需要驗證登入的示例,這樣比較清晰。
第一步:配置 gradle.properties
在gradle.properties
檔案中新增如下程式碼
#是否需要單獨執行某個模組 true:表示某個模組不作為依賴庫使用
isSingleCircleModule=true
#isSingleCircleModule=false
isSingleHomeModule=true
#isSingleHomeModule=false
第二步:配置app下的build.gradle
在app下的build.gradle
檔案配置
if (!isSingleCircleModule.toBoolean()) {
implementation project(path: ':circle')
}
if (!isSingleHomeModule.toBoolean()){
implementation project(path: ':home')
}
並註釋掉原來的依賴
// implementation project(path: ':circle')
// implementation project(path: ':home')
第三步:配置各獨立模組下的build.gradle
在circle
模組下build.gradle
檔案最頂部改動如下:
//plugins {
// id 'com.android.library'
//}
if (isSingleCircleModule.toBoolean()) {
apply plugin: 'com.android.application'
} else {
apply plugin: 'com.android.library'
}
在home
模組下build.gradle
檔案最頂部改動如下:
//plugins {
// id 'com.android.library'
//}
if (isSingleHomeModule.toBoolean()) {
apply plugin: 'com.android.application'
} else {
apply plugin: 'com.android.library'
}
第四步:看效果
上面的配置完成後,點選Sync Project with Gradle Files
等待編譯完成,可看到如下狀態:
這個時候我們選擇其中一個module執行,會發現報錯如下:
Could not identify launch activity: Default Activity not found
Error while Launching activity
很明顯,我們都知道Android程式的主入口是從清單檔案配置的,但我們的各module都還沒有做這個工作。
在circle
模組下的清單檔案中,配置如下:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.gs.circle">
<application
android:allowBackup="true"
android:icon="@mipmap/app_icon"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".CircleActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
其中的icon
、label
以及theme
都可以定義在baselib
中,這樣我們任何 module 配置的時候就可以直接引用,而無需各自複製一份了;除此之外,values
資料夾下的東西都可以移動到baselib
下,方便其他模組引用,這也就是baselib
模組的作用,如果你要細分,還可以j將公共資源放在一個獨立的模組裡,這個模組通常叫做:commonlib
,具體情況而定。
配置完清單檔案,執行後發現桌面會多出來一個 APP icon,開啟只有一個頁面,就是我們的circle
module的主頁面。home
模組的清單配置就不展示了,下面看下效果:
這個時候再切回去執行app
模組,如果發現有問題,先解除安裝再執行就ok了。但是會有一個問題,原來可以跳轉其他模組的功能,現在跳轉不了了,這其實很正常,因為在元件化開發模式下,每個 module 都是獨立的app
,所以肯定不能直接跳轉過去。
那如何實現正常跳轉呢?
需要兩步,將gradle.properties
中的程式碼修改為如下:
#isSingleCircleModule=true
isSingleCircleModule=false
#isSingleHomeModule=true
isSingleHomeModule=false
接著將circle
和home
模組的清單檔案中的 application
屬性和預設啟動配置項刪掉,然後再執行就 ok 了。
如果想將其中一個作為依賴庫使用,那麼就指匠情挑設定為false即可。
關於元件之間 AndroidManifest 合併問題
其實這個可以在正式打包的時候,註釋掉module中的相關程式碼即可,畢竟是在元件模式。那有沒有辦法解決每次都要註釋的問題呢?答案是yes.
大致思路如下:
在可獨立執行的module的res->main
資料夾下新建一個資料夾(命名自定義),然後將對應的清單檔案複製一份,名稱不需要修改,內容的差別就是前面提到的,去掉application
屬性和預設啟動配置項。<br/>
接著在對應 module 的 build.gradle 中指定表單的路徑,程式碼如下:
sourceSets {
main {
if (isSingleCircleModule.toBoolean()) {
manifest.srcFile 'src/main/module/AndroidManifest.xml'
} else {
manifest.srcFile 'src/main/AndroidManifest.xml'
}
}
}
這樣在不同的開發模式下就會讀取到不同的 AndroidManifest.xml ,然後我們需要修改這兩個表單的內容以為我們不同的開發模式服務。
單模組獨立執行小結
優點:
- 專案耦合度低,開發效率高,出現問題易排查
- 利於專案進度管理,分工明確
- 適合多人大專案
缺點:
- 前期配置比較複雜,開發過程中需要修改部分配置
- 穩定性不好把握,畢竟不是google官方出的框架,後期出問題不好處理
其實還有很多問題,實踐過的應該明白,每個專案都有自己的獨特之處,會有各種各樣的奇怪問題,但一般網上我們都可以找到解決方案。
路由攔截器使用
首先還是需要新增幾個配置,在工程下的build.gradle
檔案中新增下面這行程式碼:
classpath 'com.alibaba:arouter-register:1.0.2'
在app
模組的build.gradle
檔案下,配置改動如下:
plugins {
id 'com.android.application'
id 'com.alibaba.arouter' // 攔截器必須配置
}
配置完這兩步,按照慣例,該是編譯了。
為了演示,我這裡在app
下新建一個名為LoginActivity
的頁面,作業登入攔截後跳轉的頁面,頁面內容只有一個提示文字,這裡補貼程式碼。
然後分別在宿主模組app
、功能模組circle
和home
中去做跳轉登入頁面,看看我們的攔截器是否起到了攔截作用,下面開始定義攔截器。
要獨立執行某個模組,這裡就不再贅述了,大家自行修改配置即可。
攔截器完整程式碼如下:
/**
* Description: 登入攔截器
* Date: 2021/10/9 10:42
* <p>
* 攔截器會在跳轉之間執行,多個攔截器會按優先順序順序依次執行
* * <p>
* * priority 數值越小許可權越高
*/
@Interceptor(priority = 2, name = "登入ARouter攔截器")
public class LoginInterceptor implements IInterceptor {
private Context mContext;
@Override
public void process(Postcard postcard, InterceptorCallback callback) {
boolean isLogin = mContext.getSharedPreferences("arouterdata", mContext.MODE_PRIVATE).getBoolean("isLogin", false);
if (isLogin) {
callback.onContinue(postcard);
} else {
switch (postcard.getPath()) {
// 需要登入的攔截下來
case ARouterPath.APP_MY_INFO:
ARouter.getInstance().build(ARouterPath.LOGIN_PAGE).with(postcard.getExtras()).navigation();
break;
default:
callback.onContinue(postcard);
break;
}
}
}
/**
* 攔截器的初始化,會在sdk初始化的時候呼叫該方法,僅會呼叫一次
*
* @param context
*/
@Override
public void init(Context context) {
mContext = context;
}
}
攔截器初始化需要重新安裝才會生效,這點要注意。攔截器是不需要我們手動顯示呼叫的,而是框架通過註解來使用的,所以我們只需要寫好邏輯程式碼即可。
以上程式碼可以實現模組內和跨模組跳轉攔截,本地的登入狀態我這裡沒有處理邏輯,所以每次都會被攔截到。下面看效果:
演示效果模擬進入MyInfoActivity
頁面時需要先登入,分別從三個模組做了跳轉演示。
總結
元件化module獨立執行與合併操作起來相對繁瑣一點,但優點也很明顯。路由框架ARouter的攔截器使用起來就很簡單了,其實攔截器完全可以在學完上一篇之後,直接使用,如果元件化多模組獨立執行實際專案使用不到,可以先跳過,簡單瞭解流程即可。
Android的框架演變也很快,“三化技術”在兩年前特別火,幾乎大家都在討論,但並沒有持續多長時間就被新出的技術替代了,而作為一個開發者,自己需要掌握一個基本技能:從零開始搭建一個專案框架,並且這個框架儘可能的要跟上專案的持續發展。
本文全部程式碼已打包:關注微信公眾號code小生
回覆arouter