Android元件化專題 - 元件化配置

JakePrim發表於2018-12-20

demo地址

Android元件化專題,詳細講解元件化的使用及配置,以及實現的原理。

本文章講解了元件化的由來及配置,下期講解頁面路由跳轉及路由原理與apt

1. 元件化的由來

模組化、元件化和外掛化的關係?

(摘自百度百科)模組化是指解決一個複雜的問題時自頂向下逐層把系統劃分為若干個模組的過程,各個模組可獨立工作。

在技術開發領域,模組化是指拆分程式碼,當程式碼特別臃腫的時候,用模組化將程式碼分而治之、解耦分層。

在Android的領域模組化具體的實施方法為:元件化和外掛化。

更加詳細的講解

元件化和外掛化的區別

一套完整的外掛化或元件化都必須能夠實現單獨除錯、整合編譯、資料傳輸、UI 跳轉、生命週期和程式碼邊界這六大功能。外掛化和元件化最重要而且是唯一的區別的就是:外掛化可以動態增加和修改線上的模組,元件化的動態能力相對較弱,只能對線上已有模組進行動態的載入和解除安裝,不能新增和修改。

2. 怎樣實現元件化

要實現元件化需要考慮的問題主要包括下面幾個:

  • 程式碼解耦。將一個龐大的工程拆分解耦,這是非常耗時耗力的工作,但這也是最基礎最重要的一步
  • 資料傳遞。每個元件都有可能提供給其他元件使用,主專案與元件、元件與元件之間的資料傳遞
  • UI跳轉。
  • 元件的生命週期。元件載入、解除安裝和降維的生命週期
  • 整合除錯。在開發階段如何做到按需的編譯元件?一次除錯中可能只有一兩個元件參與整合,這樣編譯的時間就會大大降低,提高開發效率。
  • 程式碼隔離。如何杜絕耦合的產生。

實現元件化的第一步 整理程式碼拆分結構

實現元件化的第一步首先是,整理專案工程結構,明確哪些功能是可以作為元件。

建議畫圖整理專案結構,如下圖:

image.png

實現元件化的第二步 在拆分程式碼之前進行基礎配置

統一整理builde配置以及元件/整合模式的切換,實現元件的單獨除錯

  1. 在專案根部新建 config.build
ext {
    // false 整合模式

    // true 元件模式

    isComponent = false

    androidConfig = [
            compileSdkVersion: 27,
            minSdkVersion    : 19,
            targetSdkVersion : 27,
            versionCode      : 1,
            versionName      : "1.0"
    ]

    appIdConfig = [
            app   : "com.prim.component.demo",
            moudle1: "demo.prim.com.moudle1"
    ]

    supportLibrary = "27.1.1"

    dependencies = [
            appcompatv7: "com.android.support:appcompat-v7:${supportLibrary}"
    ]
}
複製程式碼
  1. 主build中加入配置
apply from: "config.gradle"

複製程式碼
  1. moudle 配置,呼叫config.gradle 中的配置
//配置apply
if (isComponent) {
    apply plugin: 'com.android.application'
} else {
    apply plugin: 'com.android.library'
}

//獲取config檔案中的配置 rootProject 專案的主物件
def config = rootProject.ext.androidConfig

def appIdConfig = rootProject.ext.appIdConfig

def dependenciesConfig = rootProject.ext.dependencies

android {
    compileSdkVersion config.compileSdkVersion

    defaultConfig {
        minSdkVersion config.minSdkVersion
        targetSdkVersion config.targetSdkVersion
        versionCode config.versionCode
        versionName config.versionName

        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"


        //如果moudle為元件  配置元件的app ID
        if (isComponent) {
            applicationId appIdConfig.app
        }

        //配置BuildConfig 程式碼中可以呼叫判斷moudle是否為元件
        buildConfigField("boolean","isComponent",String.valueOf(isComponent))

        //配置資原始檔
        sourceSets {
            main {
                if (isComponent) {//如果moudle為元件則配置 AndroidManifest 
                    manifest.srcFile 'src/main/moudle/AndroidManifest.xml'
                    // 配置元件模式下的java程式碼主檔案
                    java.srcDirs 'src/main/java','src/main/moudle/java'
                } else {
                    manifest.srcFile 'src/main/AndroidManifest.xml'
                }
            }
        }
    }

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

}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation dependenciesConfig.appcompatv7
    implementation 'com.android.support.constraint:constraint-layout:+'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'com.android.support.test:runner:+'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
}

複製程式碼
  1. app 配置,呼叫元件
apply plugin: 'com.android.application'

def config = rootProject.ext.androidConfig

def appIdConfig = rootProject.ext.appIdConfig

def dependenciesConfig = rootProject.ext.dependencies

android {
    compileSdkVersion config.compileSdkVersion
    defaultConfig {
        applicationId appIdConfig.app
        minSdkVersion config.minSdkVersion
        targetSdkVersion config.targetSdkVersion
        versionCode config.versionCode
        versionName config.versionName
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
         //配置BuildConfig 程式碼中可以呼叫判斷moudle是否為元件
        buildConfigField("boolean","isComponent",String.valueOf(isComponent))
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation dependenciesConfig.appcompatv7
    implementation 'com.android.support.constraint:constraint-layout:+'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'com.android.support.test:runner:1.0.2'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'

    if (!isComponent){//當moudle1 不為元件時才允許匯入
        implementation project(':moudle1')
    }
}

複製程式碼

下期講解頁面路由跳轉及路由原理與apt。

Android的元件化專題: 元件化配置

APT實戰

路由框架原理

模組間的業務通訊

相關文章