Android 组件化 各个Module统一配置Gradle文件

本文详细介绍了一种组件化配置方案,包括如何统一管理Gradle文件中的依赖,并实现组件既可以单独运行也能整合进壳工程中。此外,还介绍了组件化开发的优点及其在实际项目中的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一.简介

 

组件化开发中,我们可能会有很多的Module。那么就会有很多的Gradle文件。再加上项目本身的三个Gradle文件。每一个Gradle中使用的各种依赖需要统一管理。下面我们来讲解各个Module统一配置Gradle文件的内容。

 

 

 

 

 

 

二.配置

 

1.项目截图

 

 

2.说明

component_base 是基础Module 包含一些公共的引用,比如 约束布局constraintlayout。不可单独运行。


component_main 是主Module 可以单独运行。


component_ui 是UI相关Nodule 可以单独运行。

 

 

3.自定义的Gradle文件内容

ext {
    /** true 每个业务Module可以单独开发 false 每个业务Module以lib的方式运行 */
    isComponentMainModule = true//Main组件
    isComponentUIModule = true//UI组件

    /** 项目中各种版本号管理 */
    versions = [
            compileSdkVersion      : 30,//compileSdkVersion
            applicationId          : "com.wjn.componentdemo",//应用ID
            minSdkVersion          : 16,//minSdkVersion
            targetSdkVersion       : 30,//targetSdkVersion
            versionCode            : 1,//版本号
            versionName            : "1.0.0",//版本名称

            javaVersion            : 1.8,//Java SDK版本号

            appcompatVersion       : "1.2.0",//appcompat版本号
            materialVersion        : "1.2.1",//material版本号
            constraintlayoutVersion: "2.0.2",//ConstraintLayout版本号
            junitVersion           : "4.13.2",//junit版本号
    ]

    /** 项目中dependencies依赖管理 */
    dependencies = [
            appcompat       : "androidx.appcompat:appcompat:${versions["appcompatVersion"]}",
            material        : "com.google.android.material:material:${versions["materialVersion"]}",
            constraintlayout: "androidx.constraintlayout:constraintlayout:${versions["constraintlayoutVersion"]}",
            junit           : "junit:junit:${versions["junitVersion"]}",
    ]
}

 

 

4.APP的Gradle文件内容

plugins {
    id 'com.android.application'
}

android {

    compileSdkVersion rootProject.ext.versions.compileSdkVersion

    defaultConfig {
        applicationId rootProject.ext.versions.applicationId
        minSdkVersion rootProject.ext.versions.minSdkVersion
        targetSdkVersion rootProject.ext.versions.targetSdkVersion
        versionCode rootProject.ext.versions.versionCode
        versionName rootProject.ext.versions.versionName

        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    }

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

    compileOptions {
        sourceCompatibility rootProject.ext.versions.javaVersion
        targetCompatibility rootProject.ext.versions.javaVersion
    }
}

dependencies {

    /** 公共依赖包 */
    implementation project(':component_base')
    /** 是否加载 component_main */
    if (!Boolean.valueOf(rootProject.ext.isComponentMainModule)) {
        implementation project(':component_main')
    }

    /** 是否加载 component_ui */
    if (!Boolean.valueOf(rootProject.ext.isComponentUIModule)) {
        implementation project(':component_ui')
    }
}

 

 

5.component_base组件的Gradle文件内容

apply plugin: 'com.android.library'

android {

    compileSdkVersion rootProject.ext.versions.compileSdkVersion

    defaultConfig {
        minSdkVersion rootProject.ext.versions.minSdkVersion
        targetSdkVersion rootProject.ext.versions.targetSdkVersion
        versionCode rootProject.ext.versions.versionCode
        versionName rootProject.ext.versions.versionName

        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    }

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

    compileOptions {
        sourceCompatibility rootProject.ext.versions.javaVersion
        targetCompatibility rootProject.ext.versions.javaVersion
    }
}

dependencies {
    api rootProject.ext.dependencies["appcompat"]
    api rootProject.ext.dependencies["material"]
    api rootProject.ext.dependencies["constraintlayout"]
    api rootProject.ext.dependencies["junit"]
}

注意:为了避免项目中多个Module重复依赖相同的依赖问题,比如可能多个Module都会依赖约束布局constraintlayout。这样我们抽出一个Base的Module,然后在这个Module中通过api的方式引入需要的依赖。这样其他的Module只需要引入该Base即可。然后每个Module单独使用的依赖,还是和普通项目一样使用implementation引入相关依赖即可。

 

 

6.component_main组件的Gradle文件内容

/** 修改处1:根据isComponentMainModule字段 决定该Module的产物*/
if (Boolean.valueOf(rootProject.ext.isComponentMainModule)) {
    apply plugin: 'com.android.application'
} else {
    apply plugin: 'com.android.library'
}

android {

    compileSdkVersion rootProject.ext.versions.compileSdkVersion

    defaultConfig {
        /** 修改处2:根据isComponentMainModule字段 决定是否可以有applicationId 只有单独运行时才可以有applicationId*/
        if (Boolean.valueOf(rootProject.ext.isComponentMainModule)) {
            applicationId "com.wjn.component.main"
        }
        minSdkVersion rootProject.ext.versions.minSdkVersion
        targetSdkVersion rootProject.ext.versions.targetSdkVersion
        versionCode rootProject.ext.versions.versionCode
        versionName rootProject.ext.versions.versionName

        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    }

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

    /** 修改处3:sourceSets闭包 配置不同文件夹的清单文件 根据isComponentMainModule字段 */
    sourceSets {
        main {
            if (Boolean.valueOf(rootProject.ext.isComponentMainModule)) {
                manifest.srcFile 'src/main/module/AndroidManifest.xml'
            } else {
                manifest.srcFile 'src/main/AndroidManifest.xml'
            }
        }
    }

    compileOptions {
        sourceCompatibility rootProject.ext.versions.javaVersion
        targetCompatibility rootProject.ext.versions.javaVersion
    }
}

dependencies {
    /** 公共依赖包 */
    implementation project(':component_base')
    /** 本Module独立使用的依赖 */
}

 

 

7.component_ui组件的Gradle文件内容

/** 修改处1:根据isComponentUIModule字段 决定该Module的产物*/
if (Boolean.valueOf(rootProject.ext.isComponentUIModule)) {
    apply plugin: 'com.android.application'
} else {
    apply plugin: 'com.android.library'
}

android {

    compileSdkVersion rootProject.ext.versions.compileSdkVersion

    defaultConfig {
        /** 修改处2:根据isComponentUIModule字段 决定是否可以有applicationId 只有单独运行时才可以有applicationId*/
        if (Boolean.valueOf(rootProject.ext.isComponentUIModule)) {
            applicationId "com.wjn.component.ui"
        }
        minSdkVersion rootProject.ext.versions.minSdkVersion
        targetSdkVersion rootProject.ext.versions.targetSdkVersion
        versionCode rootProject.ext.versions.versionCode
        versionName rootProject.ext.versions.versionName

        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    }

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

    /** 修改处3:sourceSets闭包 配置不同文件夹的清单文件 根据isComponentUIModule字段 */
    sourceSets {
        main {
            if (Boolean.valueOf(rootProject.ext.isComponentUIModule)) {
                manifest.srcFile 'src/main/module/AndroidManifest.xml'
            } else {
                manifest.srcFile 'src/main/AndroidManifest.xml'
            }
        }
    }

    compileOptions {
        sourceCompatibility rootProject.ext.versions.javaVersion
        targetCompatibility rootProject.ext.versions.javaVersion
    }
}

dependencies {
    /** 公共依赖包 */
    implementation project(':component_base')
    /** 本Module独立使用的依赖 */
}

 

 

 

 

 

三.验证

为了验证上述配置是否正确,咱们打两个包。一个包是两个Module单独运行,一个包是两个Module作为组件为壳工程使用。

 

1.两个Module单独运行

<1> 配置开关

isComponentMainModule = true//Main组件

isComponentUIModule = true//UI组件



<2> 打出的包清单文件

<?xml version="1.0" encoding="utf-8"?>
<manifest
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:versionCode="1"
    android:versionName="1.0.0"
    android:compileSdkVersion="30"
    android:compileSdkVersionCodename="11"
    package="com.wjn.componentdemo"
    platformBuildVersionCode="30"
    platformBuildVersionName="11">

    <uses-sdk
        android:minSdkVersion="16"
        android:targetSdkVersion="30" />

    <uses-permission
        android:name="android.permission.ACCESS_WIFI_STATE" />

    <uses-permission
        android:name="android.permission.READ_EXTERNAL_STORAGE" />

    <uses-permission
        android:name="android.permission.INTERNET" />

    <application
        android:theme="@ref/0x7f0f0196"
        android:label="@ref/0x7f0e001b"
        android:icon="@ref/0x7f0c0000"
        android:allowBackup="true"
        android:supportsRtl="true"
        android:roundIcon="@ref/0x7f0c0001"
        android:appComponentFactory="androidx.core.app.CoreComponentFactory">

        <activity
            android:name="com.wjn.componentdemo.MainActivity">

            <intent-filter>

                <action
                    android:name="android.intent.action.MAIN" />

                <category
                    android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <activity
            android:name="com.wjn.component.base.BaseMainActivity" />

        <activity
            android:name="com.wjn.component.base.BaseTestActivity" />
    </application>
</manifest>

 

 

<3> 运行及验证结果

运行正常,且清单文件中不包含两个Module的Activity。验证成功。

 

 

 

2.两个Module作为组件为壳工程使用

<1> 配置开关

isComponentMainModule = false//Main组件

isComponentUIModule = false//UI组件

 

 

<2> 打出的包清单文件

<?xml version="1.0" encoding="utf-8"?>
<manifest
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:versionCode="1"
    android:versionName="1.0.0"
    android:compileSdkVersion="30"
    android:compileSdkVersionCodename="11"
    package="com.wjn.componentdemo"
    platformBuildVersionCode="30"
    platformBuildVersionName="11">

    <uses-sdk
        android:minSdkVersion="16"
        android:targetSdkVersion="30" />

    <uses-permission
        android:name="android.permission.ACCESS_WIFI_STATE" />

    <uses-permission
        android:name="android.permission.READ_EXTERNAL_STORAGE" />

    <uses-permission
        android:name="android.permission.INTERNET" />

    <application
        android:theme="@ref/0x7f0f0196"
        android:label="@ref/0x7f0e001b"
        android:icon="@ref/0x7f0c0000"
        android:allowBackup="true"
        android:supportsRtl="true"
        android:roundIcon="@ref/0x7f0c0001"
        android:appComponentFactory="androidx.core.app.CoreComponentFactory">

        <activity
            android:name="com.wjn.componentdemo.MainActivity">

            <intent-filter>

                <action
                    android:name="android.intent.action.MAIN" />

                <category
                    android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <activity
            android:name="com.wjn.component.main.MainMainActivity" />

        <activity
            android:name="com.wjn.component.ui.UIMainActivity" />

        <activity
            android:name="com.wjn.component.ui.UITestActivity" />

        <activity
            android:name="com.wjn.component.base.BaseMainActivity" />

        <activity
            android:name="com.wjn.component.base.BaseTestActivity" />
    </application>
</manifest>

 

 

<3> 运行及验证结果

运行正常,且清单文件中包含两个Module的所有Activity。验证成功。

 

 

 

 

 

 

四.总结

通过三篇文章的讲解,我们就完成了组件化的初步配置,下面我们来总结一下。

 

1.前言

普通项目的缺点(尤其是项目稍微复杂一些时)

<1> 编译运行一次很慢。

<2> 修改其中一个点,可能也需要对其他模块进行简单的测试。

<3> 提交代码很容易造成代码冲突。

<4> 排查问题,比较麻烦。

<5> ...

 

 

 

2.模块化

Android Studio中,新建一个工程默认有一个App module。然后我们还可以通过File->New->New Module 新建module。那么这里的“module” 实际就是“模块”的意思。那么模块化相比普通的项目的优点是什么呢?它相比组件化的缺点是什么呢?

 

<1> 相比普通项目优点

解决了刚刚说的普通项目的缺点。

 

<2> 相比组件化缺点

[2.1] 每个模块不能独立运行。

[2.2] 项目比较复杂时,每个模块间存在相互依赖。

[2.3] ...

 

 

 

3.组件化的优点

<1.1> 各个组件可以单独运行,方便调试。

<1.2> 我们可以把一些基础的内容放到一个基础的组件中,比如 定位功能 网络请求功能 Json解析功能 原生UI功能等等。这样其他组件只需要依赖这个基础的组件即可。其他组件不需要相互依赖。

<1.3> 组件化中依赖原则是上层可以依赖下层,下层不可依赖上层,同层之间也尽量不要相互依赖。

<1.4> ...

 

 

 

4.组件化注意事项

组件化开发中除了刚刚说的依赖问题,还需要注意一下内容。

 

为了使每一个Module既可以单独运行又可以依附壳工程运行,需要修改几个点

<1> 修改清单文件

<2> 修改Gradle文件

详情:https://blog.youkuaiyun.com/weixin_37730482/article/details/70243289 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值