安卓开发组件化

组件化开发想必在各大厂中都已经运用得十分成熟了,但是在大部分的小公司中,并没有开始运用,一方面由于业务逻辑还没复杂到需要利用组件化开发来提高开发效率,另一方面,组件化开发有未知的风险,也让人不得不望而却步。本篇并不作为组件化开发的介绍或者教程,仅仅作为之前一段时间的学习总结。


1.组件化

当应用的业务变得复杂繁重时,编译时间就会变长,尽管有各种优秀编译工具或是配置可以让编译过程变得不那么“痛苦”,但是相应的 bug 也层出不穷。在这样的背景下,组件化开发应运而生。它的出现让单元测试成为可能。
组件化开发的思路是拆分每个业务模块,让编译只专注与当前的逻辑,而不用去管其他模块,通过减少编译无关开发功能的代码,来达到减少编译时间,提高开发效率的目的。

2.试一试

目标:让一个模块既可以被依赖,又能够独立运行

首先我们创建一个工程,然后在工程目录下创建一个 module ,module 类型暂时定为 application。在这种情况下,app 和 module 都是可以独立运行的。下面,我们需要把 module 作为组件依赖给 app 主工程。

想依赖成功的话,需要在 gradle 文件中修改如下代码:

//apply plugin: 'com.android.application'
apply plugin: 'com.android.library'
android {
    ...
    defaultConfig {
        ...
        //applicationId "com.arno.testcomponent"
        ...
    }
    ...
}

那么按照上面的步骤,我们就可以简单实现一个 module 的组件化,如果报错的话,请检查一下是否有重复依赖第三方库,是不是看着挺简单的? 然而,这样做其实还有许多隐患,同时,在组件变多的时候,这种做法显得一点也不聪明,光是更改 apply plugin: 'com.android.library' 这一条,就够累人的了。因此,我们需要对它进行优化。

3.一点优化

3.1 module 的编译方式

开发安卓的朋友们一定都熟悉 java ,所以用 java 开发的思路无非是加一个开关,通过对开关的判断来选择当前 module 的模式。我们这里也是同样的想法,不过实现的方式是 groove。
为了把所有开关集中起来,我们在工程下新建了一个 .gradle 文件,这里我取名为 config.gradle

ext{
    flag=[
        //module是否是作为模块,true的时候是,false的时候可以独立运行
        isModle : true,
    ]
}

如果需要这个 .gradle 文件生效,还需要在工程目录下的 build.gradle 文件中加入下面的代码:

apply from: "config.gradle"

然后,我们就可以在 module 的 gradle 中获取这个值,从而判断这时需要以 lib 的方式加载,还是以 app 的方式加载。代码如下:

if(rootProject.ext.flag["isModule"]) {
    apply plugin: 'com.android.library'
} else {
    apply plugin: 'com.android.application'
}

如果你真的按照上面的做法做了,并把代码打包安装到手机上,那么你可能会发现,出现了非常有意思的事情:出现了两个相同的app。同时,卸载其中一个的话,另一个也会消失。

安装后的app

那么,它们打开的界面是 module 中的 MainActivity, 还是 app 中的MainActivity 呢?为此,我特意稍微修改了一下 module 中 MainActivity 的布局后,再次安装,发现它们打开的都是 app 中的 MainActivity。然而,我并不知道是为什么,正在提问中。不过没关系,我知道怎样解决。

3.2 清单文件冲突

虽然做这个部分是为了避免 module 的清单文件与 app 的设置冲突,但是神奇的是,做完这个部分后,上面的 bug 消失了。

由于不同组件是由不同的成员开发的,所以 module 中的清单文件是不同的,但是当这些 module 作为 Library 合并到主工程时,两张表便会起冲突,因为他们都有自己实现 application 的一些属性,也有自己的 MainActivity 。为此,我们需要在 module 中同时维护两张表,一张用于独立的组件开发,一张用于合并到主工程,每增加一个四大组件的时候,就需要同时给两张表中添加。

优化的方法,我们参考对 module 编译方式的优化方法。
首先,我们需要两张表,为了区分,我们将它放在不同的文件夹中去,如下图:


工程目录

其中,debug 中的 AndroidManifest.xml 和创建时候一样,而 relese 中的 AndroidManifest.xml 则把大部分属性全部删除,只留下必须的部分。

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

    <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=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" 
            </intent-filter>
        </activity>
    </application>

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

    <application android:theme="@style/AppTheme">
        <activity android:name=".MainActivity"></activity>
    </application>

</manifest>

之后需要在 module 的 build.gradle 中配置 AndroidManifest.xml 文件的路径。

android {
    ...
    //区分加载 AndroidManifest 文件
    sourceSets{
        main{
            if (rootProject.ext.flag["isModule"].toBoolean()){
                manifest.srcFile 'src/main/release/AndroidManifest.xml'
            } else {
                manifest.srcFile 'src/main/debug/AndroidManifest.xml'
            }
        }
    }
}

3.3 一些数据文件共享和sdk初始化

在组件化过程中会发现这样的问题:一个app只能配置一个 Application 子类,而在开发过程中难免要用到自定义 Application,这个时候,如果开发每个组件在合并过程中必然出现问题。因此,我们会有一个 common 库,所有组件都必须依赖这个库,而这个库中将放置所有公共的代码,如sdk初始化,一些工具类,依赖库等等。

3.4 第三方库版本号控制

实际开发中会遇到许多第三方库的依赖,有时我们需要升级一些库,但是这个过程有时会遇到错误,导致长时间的问题排查。因此我们可以将库的版本管理集中到一起。

这里我们将版本信息全部集中到之前自定义的 config.gradle 中去。

// config.gradle
ext{
    ...
    android=[
            compileSdkVersion       : 25,
            buildToolsVersion       : "26.0.1",
            minSdkVersion           : 21,
            targetSdkVersion        : 25,
    ]

    dependencies = [
            constraint      : 'com.android.support.constraint:constraint-layout:1.0.2',
            appcompatv7     : 'com.android.support:appcompat-v7:25.3.1',
    ]

}
// common build.gradle
android {
    compileSdkVersion rootProject.ext.android.compileSdkVersion
    buildToolsVersion rootProject.ext.android.buildToolsVersion

    defaultConfig {
        minSdkVersion rootProject.ext.android.minSdkVersion
        targetSdkVersion rootProject.ext.android.targetSdkVersion
        ...
    }
}

dependencies {
    ...
    compile rootProject.ext.dependencies["appcompatv7"]
    compile rootProject.ext.dependencies["constraint"]
}

以上是本次学习的全部内容,关于组件化学习的组件之间的通信可以通过 EventBus ,这个比较容易,也就不再去详细写了,接下来还在学习 ARouter 路由框架的使用和实现,后面会更新。还要努力。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,907评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,987评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,298评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,586评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,633评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,488评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,275评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,176评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,619评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,819评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,932评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,655评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,265评论 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,871评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,994评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,095评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,884评论 2 354

推荐阅读更多精彩内容