美文网首页Android 开发
Android高级进阶之-组件化开发实现

Android高级进阶之-组件化开发实现

作者: carlwu_186 | 来源:发表于2020-10-27 22:36 被阅读0次

    组件化开发的思路是:
    把项目的各个模块用library形式抽取出来,每个模块负责自己的业务,在开发阶段,各个模块可以单独打包成apk运行。最终的项目用一个壳application把这些library模块整合到一起,可以输出一个完整的apk。

    image.png

    组件化的实现步骤:
    1.项目根目录创建一个文件“config.gradle”:

    ext {
        isModule = true
    }
    

    2.项目根目录的build.gradle中引用刚刚创建的"config.gradle":

    //实现赋值与引用
    apply from: 'config.gradle'
    
    buildscript {
        //....
    }
    

    到这一步,就是告诉gradle的rootProject(项目根目录的build.gradle就会被翻译成为rootProject),添加一个字典isModule = true 。

    3.创建一个lib module项目”module1“。
    4.修改module1 的build.gradle文件(module的build.gradle也会被翻译成为project,每个project都会持有rootProject对象,可以引用rootProject的属性):

    apply plugin: 'com.android.library'
    

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

    这样,当修改isModule后,重新编译,module1就会按照 library或者application 的方式加到项目中,为library就说明它是一个库,为application就说明它是可打包apk的app项目。
    5.在壳项目”app“中修改build.gradle:

    dependencies {
        if(isModule){
            implementation project(path: ':module1')
        }
    }
    

    效果是:当module1以application方式运行时,壳app就不去依赖module1。

    到这里,我们就可以通过修改”confi.gradle"来切换"module1"的工作方式。

    补充:
    ”module1“作为application运行时,必须要告诉它的AndroidManifest.xml 指明一个LAUNCHER入口:

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

    但是作为lib运行时,我们没有这个要求。因此,”module1“需要根据isModule来指定不同的AndroidManifest.xml文件。
    lib运行时,src/main/AndroidManifest.xml 写成:

    <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="carlwu.top.module1">
        //...
    </manifest>
    

    application运行时,src/cmp/AndroidManifest.xml 写成:

    <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="carlwu.top.module1">
    
        <application
            android:theme="@style/Theme.AppCompat.Light.DarkActionBar">
            <activity android:name=".MainActivity">
                <intent-filter>
                    <action android:name="android.intent.action.MAIN" />
    
                    <category android:name="android.intent.category.LAUNCHER" />
                </intent-filter>
            </activity>
        </application>
    </manifest>
    

    我们可以在module1 的build.gradle文件中加上这样的配置:

    android {
        //...
        sourceSets {
            main {
                if (!isModule) {
                    manifest.srcFile 'src/cmp/AndroidManifest.xml'
                }
            }
        }
    }
    

    告诉编译器,application方式运行module1时,加载符合application运行要求的AndroidManifest.xml文件。

    有时我们把module1当成application运行时,需要指定自定义的Application类,那么就需要把src/cmp/AndroidManifest.xml 这么写:

    <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="carlwu.top.module1">
    
        <application
            android:name=".MyApplication"//指定自定义的Application
            android:theme="@style/Theme.AppCompat.Light.DarkActionBar">
            <activity android:name=".MainActivity">
                <intent-filter>
                    <action android:name="android.intent.action.MAIN" />
    
                    <category android:name="android.intent.category.LAUNCHER" />
                </intent-filter>
            </activity>
        </application>
    </manifest>
    

    我们就需要在module1的java目录下添加MyApplication这个类,但是如果不做处理,module1当lib被app依赖也会把类MyApplication依赖进去,这个类实际上是不需要被依赖的,最好是编译都不要参与。我们是有办法的。
    修改module1的build.gradle:

    android {
        //...
        sourceSets {
            main {
                if (!isModule) {
                    java.srcDirs 'src/cmp/java'
                    manifest.srcFile 'src/cmp/AndroidManifest.xml'
                }
            }
        }
    }
    

    意思就是告诉编译器,module1除了默认的src/main/java 目录外,还可以添加 src/cmp/java 这个目录最为源码目录,里面的类也会参与编译打包。
    效果如下:


    image.png

    相关文章

      网友评论

        本文标题:Android高级进阶之-组件化开发实现

        本文链接:https://www.haomeiwen.com/subject/yvxqyktx.html