从一搭建-Android组件化框架

首先,谈谈为什么要写这个系列的文章,严格来说是一段学习组件化的笔记。

很多小伙伴都了解组件化,也学习过,但是像我这样没有大型项目经验的,很难深入理解它的意义。直到去年公司开启了新项目,我带着2个小伙伴一起从0开发到1(当然还有产品,测试及后端每个人的功劳),突破百万日活。

随着功能模块越来越多,开发人员交替,开发风格不统一(有的mvp,有mvc,甚至有站撸activity的),工程不仅代码臃肿,目录下多达38个包。功能模块严重耦合,开发中经常引起老功能bug,或者一个bug反复出现(让你不写单元测试)。在被折磨的内心崩溃以后,终于在组件化单元测试中找到了救赎。(单元测试:请看https://www.jianshu.com/nb/26784460

吐槽完毕,开撸代码,想看基础的推荐这几篇文章(是不是拿完链接,就可以撤了):

目标

首先,我们的目标是告别臃肿,建立一个业务组件之间独立,即可集成开发,也可组件化开发的基础项目框架。

如果是简单的建立几个module,那谁都会,我们的项目里也有很多module。这里要解决的主要问题是:

  1. 组件既能独立编译开发,也可以集成开发,组件间可以灵活组合打包。
  2. 组件之间是没有关联的,如何通信,页面如何调用。(这里引入了“路由”的概念,组件间通过路由中转建立联系,Android用的是URL Scheme作为路由)

创建基础工程

app:为壳工程,只负责集成各个module。
lib_common:为公共基础库,引入大部分第三方库和工具类。
module_setting:项目各种开关,功能设置(具体什么module自己选择)
module_main:主module,暂时只有一个MainActivity。

新建工程.png

1. 创建config.gradle,对所以组件的gradle配置、第三方依赖,统一管理。(关于本地化配置gradle的教程,参考开头推荐的文章)
ext {//提取依赖,版本号,方便管理
    appVersion = [
            versionCode: 1,
            versionName: "1.0.0"
    ]
    android = [
            compileSdkVersion: 26,
            minSdkVersion    : 18,
            targetSdkVersion : 26,
    ]
    dependencies = [
            appcompat_v7       : 'com.android.support:appcompat-v7:26.1.0',
            constraintLayout   : 'com.android.support.constraint:constraint-layout:1.1.1',
            support_design             : 'com.android.support:design:26.1.0',
            support_annotations: 'com.android.support:support-annotations:26.1.0',

            testJunit          : 'junit:junit:4.12',
            textRunner         : 'com.android.support.test:runner:1.0.0',
            androidTestEspresso: 'com.android.support.test.espresso:espresso-core:3.0.0',
    ]
}

这里api、implementation、compile的区别需要注意,以免重复引入依赖:
implementation:编译的依赖只作用于当前的module
compile 与 api:二者等同,无区别

dependencies {//module引用config.gradle的配置
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    api rootProject.ext.dependencies.appcompat_v7
    api rootProject.ext.dependencies.support_design
    api rootProject.ext.dependencies.constraintLayout
2. 集成模式 和 组件化模式切换

我们需要一个开关,在gradle.properties中创建"isModule"变量,在每个module的build.gradle中,通过它来切换开发模式。

# false表示是集成化开发模式,true表示是组件化开发模式
isModule = true
if (isModule.toBoolean()) {
    apply plugin: 'com.android.application'
} else {
    apply plugin: 'com.android.library'
}

那么问题来了,组件独立编译时,需要临时的manifest,Application来初始化一些配置。并在集成模式下移除这些配置。以module_main为例:

创建debug文件夹 和 DebugApplication,创建module文件夹 和 临时Manifest

怎么灵活的切换以上文件呢,还是要用到"isModule",在build.gradle的android{}下,通过判断isModule,加载不同的AndroidManifest.xml,并在集成模式中移除debug文件夹

android {
    ...
    sourceSets {
        main {
            if (isModule.toBoolean()) {
                manifest.srcFile 'src/main/module/AndroidManifest.xml'
            } else {
                manifest.srcFile 'src/main/AndroidManifest.xml'
                java {
                    exclude 'debug/**'
                }
            }
        }
    }
3. 公共基础库(lib_common)

作为公共的基础库,除了引入依赖,还具有一下功能:

  • 引入了常用的工具类、公共/自定义widget,公共常量
  • 第三方框架(数据库,网络,图片,RxJava等)
  • permission声明
  • 一些公用的资源文件,styles、dimens、colors、drawable等等
4. app壳工程,主要功能

app壳工程,没有任何的业务代码,主要用于集成模式下:

  • build.gradle依赖各个组件
  • 配置AndroidManifest.xml
  • 声明Android应用的Application(继承lib_common的BaseApplication)。
  • 配置工程混淆文件

小结:

本章介绍了:为什么要用组件化,需要解决的问题,组件化工程的配置

项目也才搭建到这里,下一章我们会引入阿里的ARouter组件化框架,完善基础工程。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。