告别传统单一模块开发,拥抱组件化开发模式
2020-07-09 本文已影响0人
躲得过初一躲不过十五
前言
该资料中包含一些组件化开发中的重要知识点,大家可以对于文章中对于的组件化开发是视频更容易上手掌握。
一丶什么是组件化?

二丶为什么一定要掌握组件化开发?
其实在讲到为什么一定要掌握组件化开发的时候,也要刨一刨单一模块开发的坑:
-
单一模块开发中耦合太严重
类与类之间藕断丝连。 -
单一模块编译速度太慢
所以的业务逻辑都在一个模块中,每次修改哪怕一个变量,在测试的时候都要编译整个工程。 -
无法去做到功能复用
正是因为耦合太严重,一些功能在进行重用的时候需要去一个类一个类中理清楚,太麻烦。 -
团队开发不便利
开发大项目的时候都是团队开发,但是单一模块注定是团队开发的死敌。
so,单一模块从上分析还是有很多不足的,所以在这种背景下出现了组件化开发,接下来说说组件化开发的优势(其实就是弥补了单一模块的不足)
-
业务模块解耦
组件化开发中,会根据业务来拆分模块,每个模块之间没有任何的耦合,这样就能够和好的解决单一模块耦合严重的问题。 -
极大提高工程编译速度
所以的业务逻辑都在一个模块中,每次修改哪怕一个变量,在测试的时候都要编译整个工程。 -
组件化是功能重用的基石
每个业务逻辑模块是彼此独立,如果在新项目中又需要用到这个功能,可以直接复制过去使用,不需要进行任何解耦。 -
团队开发神器
如果是团队开发的话,可以每个人或着每个项目小组负责一个模块即可,无需关注其他的功能模块,这样就可以减少沟通成本,提高开发效率。
组件化和单一模块项目结构对比


三丶组件化开发的注意事项
-
要注意包名和资源文件命名冲突问题
组件化开发虽然会分将业务逻辑拆分为一个个模块,但是最终打包发布的时候依然要打包到主模块中,所以要注意包名和资源名字的命名问题。 -
Gradle中的版本号的统一管理
在组件化开发中一定会存在多个模块,每个模块都会有一个build.gradle
文件,所以必须对每个模块的build.gradle
进行统一的管理。 -
组件在Application和Library之间如何做到随意切换
因为每个模块在开发过程中都是Application
,但是最终打包发布的时候都要变为Library,所以每个模块都需要在Application
与Library
之间进行随意的切换。 -
AndroidManifest.xml文件的区分
正是因为模块要在Application与Library之间进行切换,所以在不同的状态下要加载不同的AndroidManifest.xml
。 -
Library不能在Gradle文件中有applicationId
当模块是Application的时候,在它的build.gradle
文件中会有ApplicationId
,但是当它成为Library之后,ApplicationId
就不能有了,所以要怎么去进行控制这种情况。
四丶 如何把项目组件化
如果是老项目就设计到项目迁移的问题,如果是新项目那就直接可以在创建项目的时候就进行组件化开发。具体步骤如下:
第一步:把业务模块划分好之后,创建相对应的module

最终效果如下:例子

注意: 在创建module以及Activity的时候,命名最好有自己的规则(防止类名重复以及资源名字重复)
第二步:把所有module中的版本号以及一些需要统一管理的内容进行统一管理(通过定义全局变量的方式,常用有三种方式)
1.直接定义在gradle.properties文件中,如图:

使用方式:
android {
compileSdkversion TAR_SDK_VERSION.toInteger()
buildToolsverion BUILD_TOOL_VESION
defaultConfig {
applicationId "com.maniu.member"
minSdkversion MIN_SDK_VERSION.toInteger ()
targetsdkversion TAR_SDK_VERSION.toInteger ()
versioncode VERSION_CODE.toInteger ()
versionName VERSION_NAME
testInstrumentationRunner "android.support.test.runner.AndroidJunitRunner"
}
注意: 定义在gradle.properties
文件中的全局变量都是String类型,使用的时候请先转换为需要的类型。
2.定义在工程的build.gradle文件中,如:
task clean(type:Delate) {
delete rootproject.buildDir
}
ext {
compilesdkversion = 28
bulidToolsversion = "29.0.0"
minsdkversion =21
versioncode =1
versionName = '1.0'
APP_COMPAT = ''com.android.support:appcompat-v7:28.0.0''
}
使用方式:
android {
compilesdkversion rootproject.ext.compilesdkversion
buildToolsversion rootproject.ext.buildToolsversion
defaultconfig {
applitcationId ''com.maniu.member''
minsdkversion rootproject.ext.minsdkversion
targetsdkversion rootproject.ext.targetsdkversion
versioncode rootproject.ext.versioncode
versionName rootproject.ext.versionName
testinstrumentationRunner ''android.support.test.runner.AndroidJunitRunner''
}
3.自定义gradle文件.如:
ect {
android = [
compilesdkversion : 28,
buildToolsversion : ''29.0.0'',
minsdkversion :21,
targetsdkversion :28,
versioncode : 1,
versionName :'1.0'
]
dependencies = [
appcpmpatv7: ':com.android.support:appcompat-v7:28.0.0',
]
}
定义好之后还需要是主工程的build.gradle
进行应用定义,如:

使用方式:
android {
compilesdkversion rootproject.ext.android.compilesdkversion
buildToolsversion rootproject.ext.android.buildToolsversion
defaultconfig {
applicationId ''com.maniu.member''
minsdkversion rootproject.ext.android.minsdkversion
targetsdkversion rootproject.ext.android.targetsdkversion
versioncode rootproject.ext.android.versioncode
versionName rootproject.ext.android.versionName
testInstrumentationRunner ''android.support.test.runner.AndroidJunitRunner"
}
第三步:如何让每个module都能在Application和Library之间进行随意的切换(其实很简单,定义一个boolean
类型的全局变量当做开关)


注意: 只有当module是Application的时候才具有
applicationId
,所以这里也要进行处理。
第四步:Application和Library所加载AndroidManifest.xml
文件要区分,因为他们对AndroidManifest.xml
文件的要求不一样。
处理方式很简单,直接复制一个AndroidManifest.xml
文件,一份在module是Application的时候用,一份在module是Library的时候用。如图:

Library下的AndroidManifest.xml文件

在module的
build.gradle
文件中区分使用
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultproguardFile('proguard-android-optimize.txt'),
}
}
sourcesets {
main {
if(rootproject.ext.android.is_application) {
manifest.srcFile 'src/main/AndroidMainfest.xml'
}else{
manifest.srcFile 'src/main/manifest/AndroidManifest.xml'
}
}
}
第五步:将其他业务逻辑module注入到主module中(注意Application是不能依赖其他的Application,所以要记得判断依赖的时候,其他模块是否是Application)。

到此为止,一个组件化项目的架子就搭好了。注意:以上的操作都针对所有的业务逻辑module,所有业务逻辑module都要进行这样处理。
更多面试内容,技术干货,技术交流:
star一下我的GitHub
原创不易,点点关注
