组件化、模块化本质上差不多,但是因为组件化可以转成应用的,方便团队化开发,同时个人开发的话也比较好提高效率,比如个人开发中,你开发了一款登录组件,然后其他项目要用了,或者其他同事要用了,你就可以直接把这个组件复制给它,然后那边的项目或者你的同事复制来后就可以直接用了,达到类似插拔一样的效果,极为方便,省去重复造轮子的麻烦,同时还可以降低项目复杂性,提升开发效率;

上面只是我的浅显理解 

组件化理论上来说分成3层,应用层(app壳层)、业务组件层、基础库层,其中业务组件层是依赖各个业务组件层的,然后也要依赖基础库层,然后业务组件层各个层是不互相依赖的,这个就是重点了,在项目比较复杂的时候,这个业务组件层就是可以分给其他人去开发,然后等开发完成后,在由一个管理项目的人去把这个业务组件层依赖进到app壳层,具体框架如图所示:

深度学习模型与组件连接的组件图怎么画_组件化

 。图虽然有点潦草,但是问题不大嗷,大概就这个意思

下面来说下具体怎么去实现,还有途中碰到的坑

开始实现

1.组件化编译版本、第三方库统一管理

在app根目录下创建个配置的gradle脚本

深度学习模型与组件连接的组件图怎么画_组件化_02

 然后手写配置,其中这块要注意的是要看你当前项目的gradle版本,具体坑,这里会教我们咋用ext这种扩展方式去配置一个全局的编译版本,第三方库那些,这块我这里的做法是这样的,

def dep = [:]

def android = [:]
android.gradle_plugin = 'com.android.tools.build:gradle:3.5.1'
dep.android = android


def android_support=[:]
android_support.support='com.android.support:support-v4:22.2.1'
android_support.appcompat='com.android.support:appcompat-v7:22.2.1'
android_support.constraint='com.android.support.constraint:constraint-layout:1.1.3'
dep.android_support=android_support

def support_test=[:]
support_test.runner='com.android.support.test:runner:1.0.2'
support_test.espresso='com.android.support.test.espresso:espresso-core:3.0.2'
dep.support_test=support_test

dep.junit = 'junit:junit:4.12'

def build = [:]
build.javaVersion = JavaVersion.VERSION_1_8
build.compileSdkVersion = 22
build.buildToolsVersion='28.0.3'
build.minSdkVersion = 14
build.targetSdkVersion = 22
build.BuildVersionCode = 150
build.BuildVersionName = "1.5.0"
dep.build = build

ext.dep = dep

配置好后再项目的build.gradle下引入这个配置

// Top-level build file where you can add configuration options common to all sub-projects/modules.

buildscript {
    apply from: "config.gradle"
    repositories {
        google()
        mavenCentral()
    }
    dependencies {
        classpath dep.android.gradle_plugin

        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}

allprojects {
    repositories {
        google()
        mavenCentral()
        jcenter() // Warning: this repository is going to shut down soon
    }
}

task clean(type: Delete) {
    delete rootProject.buildDir
}

然后就是日常在各个模块配置了

2.配置好就添加模块咯,这个估计都知道,我直接截图咯

深度学习模型与组件连接的组件图怎么画_系统架构_03

深度学习模型与组件连接的组件图怎么画_组件化_04

 然后就哦了

3.然后替换下你刚添加的模块中的build.gradle的那些什么编译版本呀,第三方库,support或者androidX 库那些,换成第一步中已经配置好的那些,便于后期管理,要是不这么配置的话,会因为编译的版本不一样,导致编译失败的

def build=dep.build;
android {
    compileSdkVersion build.compileSdkVersion
    buildToolsVersion build.buildToolsVersion

    defaultConfig {

        applicationId "com.glde.dlr.module_login"
        minSdkVersion build.minSdkVersion
        targetSdkVersion build.targetSdkVersion
        versionCode 1
        versionName "1.0"

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

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

dependencies {
    implementation dep.android_support.support
    implementation dep.android_support.appcompat
    implementation dep.android_support.constraint
    androidTestImplementation dep.support_test.runner
    androidTestImplementation dep.support_test.espresso
 
}

4.然后配置全局变量,区分模块是应用application还是library,这块主要就是为了区分你这个应用是开发调试的时候,还是说准备上线的时候,开发调试的时候,当然就说你设置为application嘛,不用通过app模块运行,直接运行你自己开发的那个业务组件模块,但是当你要上线了,你就要把这个状态改成上线状态了,变成library,不能da

这块可以放在之前配置好的config.gradle里头,也可以说放在gradle.properties里头

加这么一句话


#false为应用模块,否则为library模块 isRelease=false


这个isRelease随便你取名字,我这里是为了方便我后面维护叫这个鬼名字的

然后再各个模块加上判断

深度学习模型与组件连接的组件图怎么画_android_05

就这个,下面的那个是 


def build = dep.build


compileSdkVersion build.compileSdkVersion


这个东西就是之前3中配置好的

配置好后,我们可以看到,当


isRelease=false的时候,此时所有的模块都是应用级别的


深度学习模型与组件连接的组件图怎么画_深度学习模型与组件连接的组件图怎么画_06

 你看所有模块都是可以运行的,因为各个业务组件模块它跟app主模块是同一个级别的

当设置为true的时候,此时各个模块就是library了

深度学习模型与组件连接的组件图怎么画_组件化_07

我们发现只有app主模块是可以正常运行的 

5.然后添加基础组件层,这个就直接创建个library就行了,这块不在说了

碰到的坑

1.当把业务模块的转变成library的时候,运行编译的时候Android Studio会提示

> Library projects cannot set applicationId. applicationId is set to 'com.glde.dlr.module_login' in default config.
这个提示很明显了,library不能有applicationId,解决方法就是添加判断就好了

在applicationId处,添加

if(!isRelease.toBoolean()){
            applicationId "com.glde.dlr.module_login"
        }

这样就好了

2.如果有多个base基础库,并且每个业务模块都要引用的话,怎么处理会比较方便呢,这里推荐这么做:

在config.gradle中添加base基础库的配置

//配置公共基础库层
dep.dependice=[
        other:[
                ":library_base"(基础library的名字)
        ]
]

这块我等于是说声明了个other数组

然后在各个组件下的build.gradle下进行遍历获取它,然后进行依赖,直接上代码

dep.dependice.other.each{
        implementation project(it)
    }

其中each是遍历的意思,it就是other里头的东西

3.同样是当业务组件的application切换到library的时候,假如你业务组件的AndroidManifest.xml里头有配置个application,那么问题就来了,当你module变成library的时候,它是不允许有name,还有其他那些application的那些花里胡哨的属性的,就比如说,

拿本文中的应用配置举例子哈


isRelease=false,此时业务组件为还在开发中的,那么你在开发的时候,肯定会配置<Applicaiton/>及其相关熟悉的,类似


<application
        android:name=".App"
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
>

这样的,然后当你变成library后,就不需要这么多属性了,那么这块怎么处理会比较方便呢,有个解决方法,下面看操作:

1.在业务组件项目下的src/main下创建一个文件夹,然后新增一个AndroidManifest.xml文件

深度学习模型与组件连接的组件图怎么画_android_08

 2.在build.gradle中添加如下代码:

android{

   ...

   sourceSets {
        //解决资源冲突问题,比如调试的时候(应用模块)有application,
        // 与library(发版后的集成到app模块后变成lib)的application冲突
        main {
            if (isRelease.toBoolean()) {
                manifest.srcFile 'src/main/AndroidManifest.xml'
            } else {
                manifest.srcFile 'src/main/debug/AndroidManifest.xml'
            }
        }
    }
}

嗯,这样就好了,这样就不用每次在上线的时候还去手动修改AndroidManifest.xml,麻烦,而且还容易忘记这个事,那到时候就尴尬了

至此,组件化算是创建完成了,下一篇开始讲解,业务组件间如何跳转,从零开始手写路由跳转