1. 程式人生 > >Android元件化的基本操作+ARouter的基本使用(動圖演示)

Android元件化的基本操作+ARouter的基本使用(動圖演示)

一、Android元件化的基本操作

Android元件化是指將專案劃分為多個模組,並且每個模組可以單獨的作為app執行。有利於不同業務的解耦,並且可以提高編譯速度,提高協作開發的效率。

1.從新建專案開始吧,取個簡單的名字:Component:


建好之後長這樣:


2.既然是要分模組,那我們先建幾個模組:


本例中,我們新建了Base模組,First模組,Second模組,Base模組用來放置每個模組都要用到的公共內容,First模組和Second模組是功能模組。新建專案時自動生成的app模組作為一個殼模組,用來整合其他模組。

新建的模組中有很多測試的檔案,如圖:


筆者從事開發安卓一年多,尚未接觸過單元測試,所以我們先把和測試有關的檔案刪掉,程式看起來會更加的簡潔。(當然如果讀者需要這些測試檔案,將它們保留即可。)module中的versionCode和versionName也是可以刪除的。


先切換到Project模式,再刪除每個模組的androidTest資料夾、test資料夾以及build.gradle中測試有關的內容。(如果不切換到Project模式,直接在Android模式下刪除androidTest資料夾和test資料夾的話,也可以刪除這兩個資料夾中的內容,但是無法刪除這兩個資料夾,就會導致有兩個空資料夾,雖然對程式碼沒有任何影響,但是筆者是一個程式碼強迫症患者,還是想把它們徹底刪除...),將module中的versionCode和versionName也刪除,只保留app模組中的versionCode和versionName。

3.gradle的統一管理


首先在專案根目錄的build.gradle中,新增Sdk版本配置和依賴庫的版本資訊:

ext {
    cfg = [
            compileSdk       : 27,
            minSdk           : 15,
            targetSdk        : 27,
            versionCode      : 1,
            versionName      : "1.0"
]

    libs = [
            support             : "com.android.support:appcompat-v7:27.1.1",
            constraintLayout    
: "com.android.support.constraint:constraint-layout:1.1.0" ] }

添加了之後,就可以在模組的build.gradle中,使用cfg.compileSdk、libs.support等變量了。這裡的cfg、libs、compileSdk、support都是變數名,名字可以任取。

3.1.我們把各個模組需要依賴的公共庫新增到base模組的build.gradle中。

此時,base的build.gradle完整程式碼如下:

apply plugin: 'com.android.library'
android {
    compileSdkVersion cfg.compileSdk
defaultConfig {
        minSdkVersion cfg.minSdk
targetSdkVersion cfg.targetSdk
}

    buildTypes {
        release {
            minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
    }

}

dependencies {
    api fileTree(dir: 'libs', include: ['*.jar'])
    api libs.support
api libs.constraintLayout
}

3.2.然後在first模組和second模組的build.gradle中,新增base模組依賴。

此時,first模組和second模組的build.gradle相同,如下:

apply plugin: 'com.android.library'
android {
    compileSdkVersion cfg.compileSdk
defaultConfig {
        minSdkVersion cfg.minSdk
targetSdkVersion cfg.targetSdk
}
    buildTypes {
        release {
            minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
    }

}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation project(':base')
}

3.3.在app模組的build.gradle中,新增base模組,first模組,second模組的依賴。

此時,app模組下的build.gradle程式碼如下:

apply plugin: 'com.android.application'
android {
    compileSdkVersion cfg.compileSdk
defaultConfig {
        applicationId "com.simple.component"
minSdkVersion cfg.minSdk
targetSdkVersion cfg.targetSdk
versionCode cfg.versionCode
versionName cfg.versionName
}
    buildTypes {
        release {
            minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
    }
}

dependencies {
    implementation fileTree(include: ['*.jar'], dir: 'libs')
    implementation project(':base')
    implementation project(':first')
    implementation project(':second')
}

注意base中新增依賴時需要使用api關鍵字,不能使用implementation關鍵字。因為implementation關鍵字引入的庫是對外不開放的。(對外不開放的意思是指:在其他模組中引入base模組後,無法使用base模組中implementation引入的依賴庫;api關鍵字引入的庫是對外開放的。)

4.要讓first模組能夠單獨執行,需要first模組有一個啟動Activity,並且需要將first模組下的build.gradle中的apply plugin: 'com.android.library'改為apply plugin: 'com.android.application'

4.1.那麼我們就來試試吧,做一些簡單的修改,讓first模組單獨執行起來:


先是新建了一個Activity,注意這裡命名不能和其他模組重複,所以我們帶上模組名做區分,命名為FirstMainActivity。然後將FirstMainActivity作為啟動Activity,然後將first模組下的build.gradle中的apply plugin: 'com.android.library'改為apply plugin: 'com.android.application',由於first模組變成了一個單獨的可執行模組,所以app模組中不能將他作為庫依賴進來了,所以我們先將app模組下的implementation project(':first')註釋掉

切換到first模組執行:


4.2這時候會遇到崩潰,開啟Log日誌看到如下資訊:

java.lang.RuntimeException: Unable to start activity ComponentInfo{com.simple.first/com.simple.first.FirstMainActivity}: java.lang.IllegalStateException: You need to use a Theme.AppCompat theme (or descendant) with this activity.

指的是Activity必須有一個主題,那麼我們就來給FirstMainActivity設定一個主題:


我們注意到,app模組下是有一個AppTheme主題的,我們把app模組下的styles檔案和AppTheme中使用到的colors檔案都移動到base模組下的values資料夾中,然後在first模組的AndroidManifest中,給application標籤新增主題:android:theme="@style/AppTheme"(也可以只給FirstMainActivity新增主題,在application標籤中新增主題會給first模組下所有的Activity都新增這個主題)。這時候再執行first模組就沒有問題了。

app會使用預設的圖示,app名字為包名:


4.3.如果要自己設定app的名字和圖示等屬性,照著app模組下AndroidManifest中的application標籤中依樣畫葫蘆即可:

<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:roundIcon="@mipmap/ic_launcher_round"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
注:

allowBackup是指此app是否允許備份使用者資料,如果不需要的話最好關閉,網上說有開啟它有安全風險

icon是指應用圖示

roundIcon是指應用圓形圖示

label是指應用名稱

supportsRtl是指是否支援從右到左佈局(Rtl是right-to-left的縮寫),舉個例子:如果在佈局中使用了marginLeft屬性,AndroidStudio就會提示我們:


可以看到,AndroidStudio建議我們增加android:layout_marginStart="16dp",這是由於有的國家是從右到左寫字的(比如我們的阿拉伯兄弟),如果supportsRtl設定為true,佈局中設定android:layout_marginStart="16dp",那麼對於從右到左寫字的國家,佈局就會變成從右往左,方便他們使用。

5.通過第4點我們已經學會了怎麼讓模組單獨執行,但是我們想要達到的效果是:讓一個模組隨時可以單獨執行,也可以隨時切換成總app的一個模組方便打包。接下來,我們通過一個標誌位來處理這兩種情況。


5.1.先在first模組的java資料夾下,新建debug資料夾,將第4步中first模組下的AndroidManifest複製到debug資料夾中,再將first模組的AndroidManifest改回成作為總app的一個模組時的樣子。

5.2.在專案的gradle.properties中,新增isUniqueApp變數,設定為true。用isUniqueApp來標記功能模組是否作為獨立的app。isUniqueApp = true時,表示功能模組作為獨立的app執行,isUniqueApp = false時,表示功能模組作為總app的一個模組,不能單獨執行。

5.3.在first模組的build.gradle中,將:

apply plugin: 'com.android.application'

改為

if(isUniqueApp.toBoolean()){
    apply plugin: 'com.android.application'
}else{
    apply plugin: 'com.android.library'
}

意思是:如果這個模組是作為單獨app執行的,那麼apply plugin: 'com.android.application';

如果這個模組是作為總app的一個模組,那麼apply plugin: 'com.android.library'

5.4.在first模組的build.gradle中,新增:

sourceSets {
    main{
        if(isUniqueApp.toBoolean()){
            manifest.srcFile 'src/main/java/debug/AndroidManifest.xml'
}else{
            manifest.srcFile 'src/main/AndroidManifest.xml'
java{
                exclude 'debug/**'
}
        }
    }
}

意思是:如果這個模組是作為單獨app執行的,那麼manifest資源使用src/main/java/debug/AndroidManifest.xml;

如果這個模組是作為總app的一個模組,那麼manifest資源使用src/main/AndroidManifest.xml,並且排除debug資料夾中的內容

對second模組的操作和first模組一樣。

5.5.將app模組下引入first、second模組依賴的程式碼改為:

if(!isUniqueApp.toBoolean()){
    implementation project(':first')
    implementation project(':second')
}

意思是:如果first模組和second模組是作為單獨app執行的,那麼不引入first、second模組;

如果first模組和second模組是作為總app的模組,那麼引入first、second模組

6.為了標題和圖示的統一,我們為first模組和second模組設定一個應用圖示和應用名稱:


先把app模組中和圖示有關的圖片移動到base模組,以保證每個模組都可以訪問這些資原始檔。然後給application標籤設定label屬性和icon屬性

這樣就完成了專案的元件化。

二、ARouter的基本使用

ARouter是阿里巴巴開源的路由框架,可以使用ARouter方便的進行Activity隱式跳轉。

1.引入ARouter


在專案的ext.libs中,新增:

arouterCompiler     : "com.alibaba:arouter-compiler:1.1.4",
arouterApi          : "com.alibaba:arouter-api:1.3.1"

在base模組,新增:

api libs.arouterApi

在first模組和second模組,新增:(需要跳轉的每個模組都要新增)

android {
    defaultConfig {
        ...
        javaCompileOptions {
            annotationProcessorOptions {
                arguments = [ moduleName : project.getName() ]
            }
        }
    }
}

dependencies {
    ...
    annotationProcessor libs.arouterCompiler
}

2.初始化ARouter


3.實現介面跳轉:


3.1.先在FirstMainActivity中添加了路徑:

@Route(path = "/first/main")

路徑需要至少兩級,第一級是指分組。

3.2.在MainActivity中新增跳轉程式碼:

// 1. 應用內簡單的跳轉(通過URL跳轉在'進階用法'中)
ARouter.getInstance().build("/first/main").navigation();

3.3.在gradle.properties中將isUniqueApp設定為false,因為在元件化開發時,各個模組是獨立的,只有非元件化模式才能實現跳轉到不同的模組。

4.如果要跳轉時需要帶引數,程式碼為:

// 2. 跳轉並攜帶引數
ARouter.getInstance().build("/first/main")
        .withLong("key1", 666L)
        .withString("key2", "888")
        .withObject("key3", Your_Data)
        .navigation();

其中,Your_Data是一個實現了序列化的物件。


執行程式,Log控制檯可以看到:

com.simple.component D/FirstMainActivity: onCreate: 666
com.simple.component D/FirstMainActivity: onCreate: 888

以上,就是ARouter的基本使用。

原始碼已上傳: