组件化项目部署

组件化项目的意义

组件化,简单来说,就是将一个APP的业务功能进行拆分,每一个功能都是一个单独的工程,每个工程都能独立运行,且只包含自己的业务,最后整个APP由多个拆分出的组件集成而成

组件化开发的优点有以下几点

  1. 极大提高工程编译速度
    进行组件化拆分后,每个业务或者功能都是一个单独的工程,这个单独的工程可以独立编译运行,编译运行速度快,减少时间成本;
  2. 业务模块解耦,利于多人团队协作开发,提高团队开发效率
    业务组件之间不能相互引用,每个组件都把对应的业务功能放在一个工程里去实现,彼此互不打扰。 在团队开发中,每个人只负责自己的业务模块,便于开发测试;
  3. 提高功能重用性
    不同的组件实现的业务功能不同,可以像搭积木一样任意排列形成新的APP

组件化架构设计图
组件化项目部署_第1张图片

phone module 和 Android Library 的区别

phone module: 新建出可以独立运行的模块,与创建项目时自动创建的app module 是一样的,在build.gradle中 是 apply plugin: ‘com.android.application’ ,android 配置下包含applicationId;
Android Library: 新建出的Android库,不能直接运行,可被其他module引用,在build.gradle 中,是library “apply plugin: ‘com.android.library’”,Android配置下不包含applicationId.

Gradle搭建组件化项目环境

为了使多个模块之间配置一致,则可以通过引入统一配置文件进行配置,配置过程如下:

  1. 在工程中创建config.gradle文件 组件化项目部署_第2张图片
  2. 在文件中设置统一配置内容
// 必须在ext标签下进行配置
ext {
   	// 标记是测试版本还是正式发布版本,在模块中可以根据这个值进行不同的配置
    isRelease = true
 	//相关编译环境的版本配置
    androidId = [
            compileSdkVersion: 28,
            buildToolsVersion :"29.0.0",
            minSdkVersion : 21,
            targetSdkVersion : 28,
            versionCode: 1,
            versionName :"1.0"
    ]
	//不同模块的applicationId
    appId = [
            app   : "com.example.zhangzd.zujiandemo",
            order: "com.example.zhangzd.order",
            personal: "com.example.zhangzd.personal"
    ]

	//support包的版本
    supportLibrary = "28.0.0"
    //第三方依赖配置
    dependencies = [
            // ${supportLibrary}表示引用一个变量
            "appcompat"      : "com.android.support:appcompat-v7:${supportLibrary}",
            "recyclerview": "com.android.support:recyclerview-v7:${supportLibrary}",
            "constraint"     : "com.android.support.constraint:constraint-layout:1.1.3",
            "okhttp3"        : "com.squareup.okhttp3:okhttp:3.10.0",
            "retrofit"       : "com.squareup.retrofit2:retrofit:2.5.0",
            "fastjson"       : "com.alibaba:fastjson:1.2.58",
    ]
}
  1. 在工程的build.gradle 中,通过 apply from : “config.gradle” 引入配置文件;
  2. 在模块的build.gradle中应用配置文件,以APP模块为例,配置文件如下
apply plugin: 'com.android.application'
//定义变量androidId等,引入配置文件中的配置信息,
def androidId = rootProject.ext.androidId
def appId = rootProject.ext.androidId
def support = rootProject.ext.dependencies

android {
	// 通过创建的变量配置具体的信息
    compileSdkVersion androidId.compileSdkVersion
    buildToolsVersion androidId.buildToolsVersion
    defaultConfig {
        applicationId appId.app
        minSdkVersion androidId.minSdkVersion
        targetSdkVersion androidId.targetSdkVersion
        versionCode androidId.versionCode
        versionName androidId.versionName

        // 这个方法接收三个非空的参数,第一个:确定值的类型,第二个:指定key的名字,第三个:传值(必须是String)
        // 为什么需要定义这个?因为src代码中有可能需要用到跨模块交互,如果是组件化模块显然不行
        // 切记:不能在android根节点,只能在defaultConfig或buildTypes节点下
        buildConfigField("boolean", "isRelease", String.valueOf(isRelease))
        multiDexEnabled false
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    // 循环添加第三方依赖,最简单的方式,可以不循环一个一个添加
    support.each{ k, v ->
        implementation v
    }

    if (isRelease) {
        implementation project(":order")
        implementation project(":personal")
    }
}

集成化模式开发、组件化模式开发

集成化模式开发:即模块是APP的组成部分,所有的模块组装起来便是一个完整的APP,在项目中的表现形式是,在一个工程中,只有一个phone module ,其他的只能作为Android 的library被引用,只能运行phone module ,其他模块不能直接运行。例如在一个APP中,首先由主模块(phone module)app模块,其次是Oder和Personal两个library,具体如下图
组件化项目部署_第3张图片
组件化模式开发:即每个模块都是一个phone module ,可以单独运行,单独调试。例如,除了app模块外,Order和Personal 都是phone module,可以单独运行,如图
组件化项目部署_第4张图片
在团队开发过程中,每个成员可能只开发一个功能模块,不同的人开发不同功能模块,此时需要组件化开发模式,每个模块都是一个单独的phone module,可以进行单独运行和测试,加快开发速度。当打包上线时,需要将所有的功能模块与主模块一同打包成一个APP,此时需要组件化开发模式,因此需要两种模式的灵活转换,我们也可以通过gradle 的配置实现灵活转换。要进行切换,就需要知道phone module 和Android library的区别,即上边介绍的两个区别。因此两种模式的切换,即非主模块phone module 和Android library的切换。步骤如下:

  1. config.gradle 配置文件中添加 isRelease = false ,该变量标识是否是测试环境还是正式打包环境;
  2. 在非主模块中进行如下配置,以order为例:
//通过定义的isRelease 变量,判断此时是否是测试环境吗,测试环境需要切换为组件化开发模式,即每个模块都是可以单独运行的
if (isRelease) {
	// 是release时 ,将module设置为library
    apply plugin: 'com.android.library'
}else {
	// 不是是release时 ,将module设置为application
    apply plugin: 'com.android.application'
}

def androidId = rootProject.ext.androidId
def appId = rootProject.ext.androidId
def support = rootProject.ext.dependencies

android {
    compileSdkVersion androidId.compileSdkVersion
    buildToolsVersion androidId.buildToolsVersion
    defaultConfig {
        //发布版本时没有applicationID
        if (!isRelease) {
            applicationId appId.order
        }
        minSdkVersion androidId.minSdkVersion
        targetSdkVersion androidId.targetSdkVersion
        versionCode androidId.versionCode
        versionName androidId.versionName
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    support.each{k,v ->
        implementation v
    }
}

  1. 在主模块中,配置当非release模式下,不引用order等模块,当release模式时,引用
dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    support.each{k,v ->
        implementation v
    }
	//  release 时才进行依赖
    if (isRelease) {
        implementation project(":order")
        implementation project(":personal")
    }
}

经过以上的配置,我们只需要在config.gradle 中更改isRelease变量,即可进行两种模式的自由切换。
组件化项目部署_第5张图片

组件化开发时的临时代码,集成化打包时动态隔离

当我们切换到集成开发模式并打包成一个Apk时,会发现一个问题,那就是在非主模块,我们的一些测试文件,比方说mainActivity等,只是在测试时才会用到,打包时不需要打包到apk,这个需要怎么解决呢?
组件化项目部署_第6张图片
我们可以通过配置sourceSet设置资源路径来解决这个问题

  1. 在非主模块的main路径下,新建debug路径,该路径下创建测试环境时的AndroidManifest.xml文件;
  2. 在Java.xxx.xxx.xxx.下创建debug,该路径下存放测试的Java代码
    组件化项目部署_第7张图片
  3. 在该模块的build.gradle中配置sourceSet
if (isRelease) {
    apply plugin: 'com.android.library'
} else {
    apply plugin: 'com.android.application'
}

def androidId = rootProject.ext.androidId
def appId = rootProject.ext.androidId
def support = rootProject.ext.dependencies

android {
    compileSdkVersion androidId.compileSdkVersion
    buildToolsVersion androidId.buildToolsVersion
    defaultConfig {
        //发布版本时没有applicationID
        if (!isRelease) {
            applicationId appId.order
        }
        minSdkVersion androidId.minSdkVersion
        targetSdkVersion androidId.targetSdkVersion
        versionCode androidId.versionCode
        versionName androidId.versionName
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }

    // 配置资源路径,方便测试环境中的内容不会被打包到apk中去
    sourceSets {
        main{
            if (isRelease) {
                //集成化模式,整个项目打包成一个apk
                manifest.srcFile 'src/main/AndroidManifest.xml'
                java {
                    // debug 目录下的文件不需要打包到apk中去
                    exclude '**/debug/**'
                }
            }else {
                //组件化模式,需要单独运行
                manifest.srcFile 'src/main/debug/AndroidManifest.xml'
            }
        }
    }
}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'androidx.appcompat:appcompat:1.0.2'
    implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
    support.each { k, v ->
        implementation v
    }
}

  1. 重新编译打包,就可以了
    最后查看apk ,打出的apk中不包含测试用的A,B等类
    组件化项目部署_第8张图片

你可能感兴趣的:(Android组件化,组件化,Android,gradle)