组件化项目部署实例

2019-12-26  本文已影响0人  migill
1、组件化项目的意义

开发需求:不相互依赖、可以相互交互、任意组合、高度解耦
团队效率:分模块打包、测试、统一版本管理>


2、Phone Module和Android Library区别、切换
3、新建common公共库、order订单库、personal个人信息库

模块中有小绿点的是可以单独运行的,模块中有柱状图的是不可以单独运行的。在做组件化模式的时候需要子模块可以独立运行,在做集成化模式的时候需要打包整个项目apk,子模块不可独立运行。

4、gradle搭建组件化项目环境

环境:Android Studio3.4.1+Gradle5.1.1
思考:我们在修改版本号的时候,需要修改各个子模块中的版本号,万一漏了有一个怎么办?这个时候就需要把版本号与引入的第三方库统一管理起来。
\color{red}{在项目的根目录下面新建一个config.gradle文件,用于做版本与引入三方库的统一管理}\

//如果要添加多个自定义的属性,需要在ext代码块中引入
ext {
    // 定义一个项目全局变量isRelease,用于动态切换:组件化模式 / 集成化模式
    // false: 组件化模式(子模块可以独立运行),true :集成化模式(打包整个项目apk,子模块不可独立运行)
    isRelease = false
    // 建立Map存储,对象名、key可以自定义
    androidId = [
            compileSdkVersion: 28,
            buildToolsVersion: "29.0.0",
            minSdkVersion    : 24,
            targetSdkVersion : 28,
            versionCode      : 1,
            versionName      : "1.0"
    ]

    appId = ["app"     : "com.migill.modular",
             "order"   : "com.migill.modular.order",
             "personal": "com.migill.modular.personal"]

    url = [
            "debug"  : "https://11.22.33.44/debug",
            "release": "https://55.66.77.88/release"
    ]
    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",
    ]
}

\color{red}{在根目录的build.gradle头部加入自定义gradle}\

apply from: "config.gradle"

\color{red}{修改app模块下的build.gradle文件}\

1、buildConfigField("boolean", "isRelease", String.valueOf(isRelease))这句是什么意思?
是在BuildConfig文件中新增一个isRelease属性。


2、为什么是在isRelease为true的时候引入order和personal 模块?
是因为isRelease为false的时候是组件化模式,order与personal模块都是application模块,application模块是不能引用application模块的。
apply plugin: 'com.android.application'

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

android {
    compileSdkVersion rootAndroidId.compileSdkVersion
    buildToolsVersion rootAndroidId.buildToolsVersion
    defaultConfig {
        // app子模块在组件化开发中,默认为application
        applicationId appId.app
        minSdkVersion rootAndroidId.minSdkVersion
        targetSdkVersion rootAndroidId.targetSdkVersion
        versionCode rootAndroidId.versionCode
        versionName rootAndroidId.versionName
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
        // 切记:不能在android根节点,只能在defaultConfig或buildTypes节点下
        buildConfigField("boolean", "isRelease", String.valueOf(isRelease))
    }

    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 }
    implementation project(':common') // 公共基础库
    // 如果是集成化模式,做发布版本时。各个模块都不能独立运行了
    if (isRelease) {
        implementation project(':order')
        implementation project(':personal')
    }
}

\color{red}{修改order模块下的build.gradle文件}\

  • isRelease=true:集成化模式(打包整个项目apk,子模块不可独立运行)需要配置成Android Library
  • isRelease=false:组件化模式(子模块可以独立运行)需要配置成Phone Module
if (isRelease) { // 如果是发布版本时,各个模块都不能独立运行
    apply plugin: 'com.android.library'
} else {
    apply plugin: 'com.android.application'
}

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

android {
    compileSdkVersion rootAndroidId.compileSdkVersion
    buildToolsVersion rootAndroidId.buildToolsVersion
    defaultConfig {
        if (!isRelease) { // 如果是集成化模式,不能有applicationId
            applicationId appId.order // 组件化模式能独立运行才能有applicationId
        }
        minSdkVersion rootAndroidId.minSdkVersion
        targetSdkVersion rootAndroidId.targetSdkVersion
        versionCode rootAndroidId.versionCode
        versionName rootAndroidId.versionName
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
        buildConfigField("boolean", "isRelease", String.valueOf(isRelease))
    }

    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 }
    implementation project(':common') // 公共基础库
}

\color{red}{修改personal模块下的build.gradle文件}\

if (isRelease) { // 如果是发布版本时,各个模块都不能独立运行
    apply plugin: 'com.android.library'
} else {
    apply plugin: 'com.android.application'
}

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

android {
    compileSdkVersion rootAndroidId.compileSdkVersion
    buildToolsVersion rootAndroidId.buildToolsVersion
    defaultConfig {
        if (!isRelease) { // 如果是集成化模式,不能有applicationId
            applicationId appId.personal // 组件化模式能独立运行才能有applicationId
        }
        minSdkVersion rootAndroidId.minSdkVersion
        targetSdkVersion rootAndroidId.targetSdkVersion
        versionCode rootAndroidId.versionCode
        versionName rootAndroidId.versionName
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
        buildConfigField("boolean", "isRelease", String.valueOf(isRelease))
    }

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

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 }
    implementation project(':common') // 公共基础库
}

总结:app、order、personal模块的build.gradle的修改都是围绕如下两点:

5、集成化模式开发、组件化模式开发
6、组件化开发的临时代码,集成化打包时动态隔离

思考:比如我们在order中创建了A、B、C三个测试类,在集成环境打包的时候,我不希望打包到APK中去,这个怎么办呢?


这个时候就可以用到资源配置,方便测试环境,打包不继承到正式环境

如下图,在main下创建debug目录放AndroidManifest.xml文件,在com.migill.modular.order.debug下放测试的文件

修改isRelease = true,编译正式的APK,可以发现A、B、C、Order_DebugActivity都没有打包到正式环境中。

修改isRelease = false,单独运行order模块。首页就变成了Order_DebugActivity的页面了。
android {
...
    // 配置资源路径,方便测试环境,打包不集成到正式环境
    sourceSets {
        main {
            if (!isRelease) {
                // 如果是组件化模式,需要单独运行时
                manifest.srcFile 'src/main/debug/AndroidManifest.xml'
            } else {
                // 集成化模式,整个项目打包apk
                manifest.srcFile 'src/main/AndroidManifest.xml'
                java {
                    // release 时 debug 目录下文件不需要合并到主工程
                    exclude '**/debug/**'
                }
            }
        }
    }
...
}
上一篇 下一篇

猜你喜欢

热点阅读