注册

Android组件化开发笔记

Modularization

什么是组件化

组件化就是将一个app拆分成不同的组件,每一个组件都是一个独立的module。

组件化的意义

组件化能降低耦合性,而耦合性低就能提高维护性。

于此同时由于组件间是独立的,所以组件与组件间耦合性低,所以我们在团队开发的时候可以以组件为分割单位,这样就能提高开发效率。

如何进行组件化

组件化是依靠gradle实现的。所以不会gradle的得去学学基础语法。当然也可以不学,只是说看别人写的代码看的半懂不懂的。

第一步创建Module

起点是一个全新的Project

image-20210818192909793

创建Module有好几种方法。

  • 右击new Module

    image-20210818193028977

    这个得注意位置哦,不然new出来全在app包下不是很好,通常我们的module是和app平级的。也就是说在大project下面。

    在我的这个demo中就是Modularization下面

  • 点击File new一个Module

    image-20210818193107528

这里我创建了3个module,一个lib

image-20210818193618429

注意命名,module是module_模块名,lib是lib__库名称.

简单区分以下module和lib,lib就是不显示页面的模块,module就是一个页面模块的集合。

将版本信息配置到一个gradle文件中

Tips:
fileName :app_versions.gradle

//applicationIds
def appIds = [:]
appIds.module_main = "com.example.module_main"
appIds.module_one = "com.example.module_one"
appIds.module_two = "com.example.module_two"
appIds.app = "com.example.modularization"
ext.appIds = appIds

将该gradle文件配置到project的build.gradle中

// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
apply from: 'app_versions.gradle'
ext{
app_configs = "$rootDir/app_config.gradle"
}
repositories {
google()
mavenCentral()
}
dependencies {
classpath "com.android.tools.build:gradle:7.0.0"
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.5.20"

// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}

task clean(type: Delete) {
delete rootProject.buildDir
}

配置gradle的编译插件

先在gradle.properties,加入一个变量判断是否是发行状态

组件化中有两种状态,一种是debug状态,一个是发行状态,

  • debug状态也就是开发阶段,这个阶段每一个模块都是一个独立的app,可以独立运行
  • release发行状态,这个状态下只有app模块可以独立运行,其他的模块都是lib,依托于app模块。

image-20210818194002652

然后创建了一个app_config.gradle文件

image-20210818194518257

编写代码使得module_XX能在lib和app中切换状态。

这里有一点需要注意我们在gradle.propergies虽然写了一个isRelease的bool变量但是其实gradle这里获取的是一个string,得用toBoolean()进行转化。

image-20210818194838453

if (isRelease.toBoolean()){
if (project.name != 'app') apply plugin: 'com.android.library'
else apply plugin: 'com.andorid.application'
}
else{
if (project.name.matches('module_.+') || project.name == 'app') apply plugin: 'com.android.application'
else if (project.name.matches('lib_.+')) apply plugin: 'com.android.library'
}

然后加入必要的依赖

apply plugin: 'kotlin-android'
apply plugin: 'kotlin-kapt'

配置Manifest文件

android{
`````

sourceSets{
main{
if (isRelease.toBoolean()){
manifest.srcFile "src/main/AndroidManifest.xml"
}else {
if (project.name.matches('module_.+')){
manifest.srcFile "src/main/manifest/AndroidManifest.xml"
}else if (project.name.matches('lib_.+') || project.name == 'app'){
manifest.srcFile "src/main/AndroidManifest.xml"
}
}
}
}


`````
}

然后对module的manifest文件进行一点变动

在main文件夹下创建manifest文件夹,然后把debug状态的manifest的文件放进去。

image-20210818200716961

debug状态下的文件(这个状态下编译的文件是apk所以需要配置启动页和一些application的选项)

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


<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/Theme.Modularization">

<activity
android:name=".MainMainActivity"
android:exported="true">

<intent-filter>
<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>

</manifest>

release状态下的manifest文件(这个状态下的编译文件是aar文件所以只需要注册一个activity,其余的都不需要)

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


<application>
<activity
android:name=".MainMainActivity"
android:exported="true" />

</application>

</manifest>

其余的module_XX,模块也是按照这样改。

配置applicationId

由于application才有applicationId,所以lib是没有applicationId的,而module在application和module之间疯狂切换,说以是有必要进行设置的。

if (isRelease.toBoolean()) {
applicationId "com.example.modularization"
}else {
if (project.name.matches('module_.+') || project.name == 'app') {
applicationId appIds[project.name]
}
}

之后在project的build.gradle中加点变量方便其gradle文件访问app_config.gradle文件(注意要加等号‘=’)

buildscript {
ext{
app_config = "$rootDir/app_config.gradle"
}
repositories {
google()
mavenCentral()
}
dependencies {
classpath "com.android.tools.build:gradle:7.0.0"
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.5.20"

// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}

module引用app_config.gradle

之前

plugins {
id 'com.android.application'
id 'kotlin-android'
}

android {
compileSdk 30

defaultConfig {
applicationId "com.example.module_main"
minSdk 21
targetSdk 30
versionCode 1
versionName "1.0"

testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}

buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = '1.8'
}
}

dependencies {

implementation 'androidx.core:core-ktx:1.3.2'
implementation 'androidx.appcompat:appcompat:1.2.0'
implementation 'com.google.android.material:material:1.3.0'
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
testImplementation 'junit:junit:4.+'
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
}

之后

apply from: app_configs

dependencies {

implementation 'androidx.core:core-ktx:1.3.2'
implementation 'androidx.appcompat:appcompat:1.2.0'
implementation 'com.google.android.material:material:1.3.0'
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
testImplementation 'junit:junit:4.+'
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
}

其余的lib和module都是这样

把android闭包下的一些属性进行抽离


def android_versions = [:]
android_versions.sdk_version = 30
android_versions.min_version = 21
android_versions.target_version = 30
android_versions.version_code = 1
android_versions.version_name = "1.0"

def kotlin_options = [:]
kotlin_options.jvm_target = '1.8'
android_versions.kotlin_options = kotlin_options

ext.android_versions = android_versions

app_config.gradle的内容

if (isRelease.toBoolean()){
if (project.name != 'app') apply plugin: 'com.android.library'
else apply plugin: 'com.andorid.application'
}
else{
if (project.name.matches('module_.+') || project.name == 'app') apply plugin: 'com.android.application'
else if (project.name.matches('lib_.+')) apply plugin: 'com.android.library'
}

apply plugin: 'kotlin-android'
apply plugin: 'kotlin-kapt'

android {
compileSdk android_versions.sdk_version

defaultConfig {
if (isRelease.toBoolean()) {
applicationId "com.example.modularization"
}else {
if (project.name.matches('module_.+') || project.name == 'app') {
applicationId appIds[project.name]
}
}

minSdk android_versions.min_version
targetSdk android_versions.target_version
versionCode android_versions.version_code
versionName android_versions.version_name

testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}

sourceSets{
main{
if (isRelease.toBoolean()){
manifest.srcFile "src/main/AndroidManifest.xml"
}else {
if (project.name.matches('module_.+')){
manifest.srcFile "src/main/manifest/AndroidManifest.xml"
}else if (project.name.matches('lib_.+') || project.name == 'app'){
manifest.srcFile "src/main/AndroidManifest.xml"
}
}
}
}

buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = android_versions.kotlin_options.jvm_target
}
}

0 个评论

要回复文章请先登录注册