Android组件化系列之module和application相互切换配置

问题

开发时经常是多人协同开发,每个人负责不同的功能,首先由项目主负责人搭建项目框架,之后每个人通过 git 下载项目,然后就开始开发各自的功能。有些独立的功能模块自成一个 module,比如相机相册、二维码等等,这样可以提高工程的复用性,不同module需要使用你的模块直接跳转过来即可。虽然抽出来一个独立的module,但是如何把这个module变成一个独立的application更加方便我们的编译、调试和开发呢?而不是开发时需要编译整个项目,这样的编译速度大打折扣,例如我们的项目,编译一次就需要好几分钟,这是不能容忍的。这个时候我们就可以单独的创建一个 Application ,最后合并时只需把你的 Application 当成一个 Module,壳工程直接跳转到你的 Module  就可以了。这样在开发过程中只用编译自己的application即可,可以极大提高我们的开发效率。无需编译整个project,就是因为功能模块在开发过程中以Application的形式存在。当业务功能整合时,才以Library的形式存在。
那么自己创建的 Module 怎么才能变成 Application 呢?或者说 Module 和 Application 之间怎样切换方便调试?下面将详细介绍

看完整项目

详解

步骤一:为了让各个module的库版本统一,我们在工程根目录下新建一个config.gradle配置文件,

config.gradle内容就是配置了一些基础参数,是否切换成application的参数isModule就在这个文件里,后续我们修改这个值就可以完成library与application的切换。

ext {  //extend
    // false: 组件模式
    // true :集成模式
    isModule = false
    android = [
            compileSdkVersion: 28,
            minSdkVersion    : 15,
            targetSdkVersion : 28,
            versionCode      : 1,
            versionName      : "1.0"
    ]

    appId = ["app"  : "com.example.dn_component",
             "module1": "com.example.module1",
             "module2" : "com.example.module2" ]

    supportLibrary = "28.0.0"
    dependencies = [
            "appcompat-v7"     : "com.android.support:appcompat-v7:${supportLibrary}",
    ]
}

步骤二:在根build.gradle中引入config.gradle,并在其他module中使用:

(1)根目录引入这个config.gradle文件:

//相当于引入头文件 将 config中的内容引入进来
apply from: "config.gradle"

(2)各个module以及主工程的build处的使用如下,也即各个module的gradle文件使用config中的统一变量进行配置:

//赋值与引用
def cfg = rootProject.ext.android
def appId = rootProject.ext.appId

android {
    compileSdkVersion cfg.compileSdkVersion

    defaultConfig {
        minSdkVersion cfg.minSdkVersion
        targetSdkVersion cfg.targetSdkVersion
        versionCode cfg.versionCode
        versionName cfg.versionName

        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
        consumerProguardFiles 'consumer-rules.pro'

        javaCompileOptions {
            annotationProcessorOptions {
                arguments = [ moduleName : project.getName() ]
            }
        }

    }

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

}

步骤三:由于module2需要配置成module和application可以相互切换的形式,单独的application当然需要启动activity了,其实就是一个普通的Android工程,需要添加application自己的activity入口以及manifest文件,配置好的目录结构:

从上图中我们可以看到有两个AndroidManifest.xml,一个在app目录下,一个在module下,主要是做什么用的呢?下面先看一下在module2的gradle配置文件中android {}中的一段配置:

//资源配置
        sourceSets{
            main{
                //在组件模式下 使用不同的manifest文件
                if(!isModule){
                    manifest.srcFile 'src/main/module/AndroidManifest.xml'
                    java.srcDirs 'src/main/module/java','src/main/java'

                }else{
                    manifest.srcFile 'src/main/AndroidManifest.xml'
                }
            }
        }

 isModule变量的作用主要用来配置这个用户中心模块是不是需要集成到主的APP中去,如果是true则是集成到主APP,这个模块就会变成library库,如果是false,那么它就可以当成APP安装到用户手机上。这是因为在module2中的build.gradle文件中加入了这样的代码来控制此库是library还是APP:

扫描二维码关注公众号,回复: 8588665 查看本文章

if (isModule) { apply plugin: 'com.android.library' } else { apply plugin: 'com.android.application' }

(1)module2的gradle配置文件如下(根据config中的isModule参数进行判断是library还是Application):

//apply plugin: 'com.android.library'
//根据isModule标签动态的切换 集成/组件模式
if (isModule){
    apply plugin: 'com.android.library'
}else{
    apply plugin: 'com.android.application'
}

def cfg = rootProject.ext.android
def appId = rootProject.ext.appId

android {
    compileSdkVersion cfg.compileSdkVersion

    defaultConfig {
        minSdkVersion cfg.minSdkVersion
        targetSdkVersion cfg.targetSdkVersion
        versionCode cfg.versionCode
        versionName cfg.versionName

        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
        consumerProguardFiles 'consumer-rules.pro'

        javaCompileOptions {
            annotationProcessorOptions {
                arguments = [ moduleName : project.getName() ]
            }
        }

        //添加一条 boolean类型的变量
        buildConfigField("boolean","isModule",String.valueOf(isModule))

        //组件模式下
        if (!isModule){
            applicationId appId['module2']
        }

        //资源配置
        sourceSets{
            main{
                //在组件模式下 使用不同的manifest文件
                if(!isModule){
                    manifest.srcFile 'src/main/module/AndroidManifest.xml'
                    java.srcDirs 'src/main/module/java','src/main/java'

                }else{
                    manifest.srcFile 'src/main/AndroidManifest.xml'
                }
            }
        }

    }

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

}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])

    implementation 'com.android.support:appcompat-v7:28.0.0'
    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'


    implementation project(':base')

}

这里我们新建的是普通的Android module,后面自己手动添加了这么几个目录,系统创建的module是没有application和layout、默认的activity这些的,步骤如下:

(2)新建activity、以及布局文件、manifest文件、application

新建的这些都是空的,只是manifest里面需要添加入口的activity即可,这里需要维护两套manifest.xml文件:

  • 新建application的activity
public class Module2Activity extends Activity {

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_module2);

    }
}
  • 新建application的manifest文件: 
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.dn_alan.module2">

    <application android:name=".Module2Application">
        <activity android:name="com.example.module2.Module2Activity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
</manifest>
  •  原始的module的manifest文件是不需要activity的入口,
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.module2" />

 如此我们只需要在config.gradle配置文件中的改动一下isModule变量的参数即可实现用户模块的可插拔形式集成和独立运行。

配置完上述步骤后,我们这里就有了两个可选择编译的application,

当然,当开发完毕,需要将module2编译到主工程时,把config.gradle文件中的isModule置为true即可。

完整的项目地址:https://github.com/buder-cp/DesignPattern/tree/master/buder_DN_component

发布了189 篇原创文章 · 获赞 81 · 访问量 21万+

猜你喜欢

转载自blog.csdn.net/cpcpcp123/article/details/103844376
今日推荐