安卓组件化没你想得那么难

作者: 极客简讯 | 来源:发表于2017-09-14 13:09 被阅读375次

刚刚get到的新技能,跟大家分享

在网上对于组件化的定义是这样的

将一个app分成多个模块,每个模块都是一个组件(Module),开发的过程中我们可以让这些组件相互依赖或者单独调试部分组件等,但是最终发布的时候是将这些组件合并统一成一个apk,这就是组件化开发。

但是这样说感觉太书面化了,经过一段时间的了解学习,就我而言,安卓组件化的根本是application与library之间的相互转换

Android Studio上开发的朋友们都知道 在项目每一个module中的build文件中的第一句话是这样的

   apply plugin: 'com.android.application'

或者是这样的

   apply plugin: 'com.android.library'

用来将module指定为app或者一个库,而组件化则是在它的基础上加了一个最为普通的if else ,如下:

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

其中 isDebug是在项目gradle.properties文件中定义的一个全局变量,用来指定是否为开发模式。
到这里,相信大家应该想到了组件化的根本原理,进行开发模式的时候,将单个模块设为 apply plugin: 'com.android.application',进行代码编写,打包的时候,则是由一个主程序来控制,将所有的module进行整合,形成一个完整的app。

接下来,我们来看看一个简单的小案例

1最终效果(很简单):

案例效果.gif

2.项目地址:

https://github.com/zw21544182/ModuleDemo

3.项目结构

项目结构.png

4.具体分析

1.项目的gradle.properties中定义一个全局变量isDebug来判断是否为调试模式,如图:


gradle.properties.png

2.再来看看app first second 三个模块中的build.gradle文件
app build.gradle

if (!isDebug.toBoolean()) {
    apply plugin: 'com.android.application'
} else {
    apply plugin: 'com.android.library'
}
android {
    compileSdkVersion 25
    buildToolsVersion "26.0.1"
    defaultConfig {
        if (!isDebug.toBoolean()) {
        applicationId "zw.moduledemo"}
        minSdkVersion 23
        targetSdkVersion 25
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    compile fileTree(include: ['*.jar'], dir: 'libs')
    androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
        exclude group: 'com.android.support', module: 'support-annotations'
    })
    compile 'com.android.support:appcompat-v7:25.3.1'
    compile 'com.android.support.constraint:constraint-layout:1.0.2'
    testCompile 'junit:junit:4.12'
    if (!isDebug.toBoolean()) {
        compile project(':first')
        compile project(':second')
    }
}

first build.gradle

if (isDebug.toBoolean()) {
    apply plugin: 'com.android.application'
} else {
    apply plugin: 'com.android.library'
}
android {
    compileSdkVersion 25
    buildToolsVersion "26.0.1"
    resourcePrefix "first_"
    defaultConfig {
        if (isDebug.toBoolean()) {
            applicationId "zw.first"
        }
        minSdkVersion 23
        targetSdkVersion 25
        versionCode 1
        versionName "1.0"

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

    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
    sourceSets {
        main {
            if (isDebug.toBoolean()) {
                manifest.srcFile 'src/main/AndroidManifest.xml'
            } else {
                manifest.srcFile 'src/main/module/AndroidManifest.xml'
            }
        }
    }
}

dependencies {
    compile fileTree(include: ['*.jar'], dir: 'libs')
    androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
        exclude group: 'com.android.support', module: 'support-annotations'
    })
    compile 'com.android.support:appcompat-v7:25.3.1'
    compile 'com.android.support.constraint:constraint-layout:1.0.2'
    testCompile 'junit:junit:4.12'
        compile project(':second')
}

second build.gradle


    apply plugin: 'com.android.library'


android {
    compileSdkVersion 25
    buildToolsVersion "26.0.1"

    defaultConfig {

        resourcePrefix "second_"
        minSdkVersion 23
        targetSdkVersion 25
        versionCode 1
        versionName "1.0"

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

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

}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
        exclude group: 'com.android.support', module: 'support-annotations'
    })
    compile 'com.android.support:appcompat-v7:25.3.1'
    compile 'com.android.support.constraint:constraint-layout:1.0.2'
    testCompile 'junit:junit:4.12'
}

build.gradle文件中最为核心的是isDebug的值,可以通过它来控制是否为application
其次还需要注意的
(1) applicationId 关键字,library是不允许设置的
(2) resourcePrefix 关键字,用来防止项目资源冲突,如下图:

命名不规范.png

当设置了resourcePrefix 而资源却没有按照规范来命名时,它会进行提示,但运行时不会报错。(容易忘记)
(3)AndroidMainfest文件 作为application 和library AndroidMainfest文件是不同的,我们需要新建一个AndroidMainfest 然后在build.gradle中通过isDebug的值来判断用哪个AndroidMainfest

    sourceSets {
        main {
            if (isDebug.toBoolean()) {
                manifest.srcFile 'src/main/AndroidManifest.xml'
            } else {
                manifest.srcFile 'src/main/module/AndroidManifest.xml'
            }
        }
    }

(4)还有就是导包的问题,这个按需求来就行
3 再来看看app模块中的 AndroidMainfest文件

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="zw.moduledemo">
    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name="zw.first.activity.MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity android:name="zw.second.SeMainActivity" />
    </application>
</manifest>

只进行了,简单的两个activity配置,复杂的逻辑包括权限申请等 那些都可以在库文件里进行声明,app模块只负责程序的数据初始化以及界面的注册。
所以说 组件化的好处相对与大型app开发以及协同来说,优势是不容小觑的,有着易维护,易扩展,高度解耦的功能。

相关文章

  • 安卓组件化没你想得那么难

    刚刚get到的新技能,跟大家分享 在网上对于组件化的定义是这样的 将一个app分成多个模块,每个模块都是一个组件(...

  • 安卓组件化

    代码地址:https://github.com/ewgcat/ComponentDemo 上图是目前比较普遍使用的...

  • 深入学习Activity

    前言 Activty是安卓四大组件中最为常用的组件,通常也是安卓开发者最先接触的安卓组件。安卓开发的工作也主要是围...

  • 【翻译】安卓架构组件(2)-添加组件到你的项目中

    相关文章: 【翻译】安卓架构组件(1)-App架构指导 【翻译】安卓架构组件(3)-处理生命周期 【翻译】安卓架构...

  • 安卓开发组件化

    组件化开发想必在各大厂中都已经运用得十分成熟了,但是在大部分的小公司中,并没有开始运用,一方面由于业务逻辑还没复杂...

  • 【翻译】安卓架构组件(1)-App架构指导

    相关文章: 【翻译】安卓架构组件(2)-添加组件到你的项目中 【翻译】安卓架构组件(3)-处理生命周期 【翻译】安...

  • modularization 安卓组件化demo

    modularization 安卓组件化demo 可根据自己需求修改模块,感谢star issues follow...

  • 画画,没你想得那么难

    如何才能说服一名妈妈画画呢? 我想最诱惑的理由莫过于,你至少可以给孩子少报一个班。 一定有人会说,那我是不是要弹弹...

  • 减肥?没你想得那么难!

    让一个女生开心立竿见影的方式有两个:一是夸她变瘦了,二是夸她更美了。而在这个六一,世界上最开心的宝宝中有我一个。因...

  • 【翻译】安卓架构组件(6)-Room持久化类库

    相关文章: 【翻译】安卓架构组件(1)-App架构指导 【翻译】安卓架构组件(2)-添加组件到你的项目中 【翻译】...

网友评论

    本文标题:安卓组件化没你想得那么难

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