Bootstrap

【Android】组件化开发入门

引入

组件是什么?

组件(Component)是对数据和方法的一个封装,其核心特点包括功能单一、高内聚、低耦合、可复用。它通常是业务逻辑中最小的可划分单元,具备清晰的功能边界,方便集成到更大的应用中。

为什么使用组件化开发?

  1. 降低耦合度,提升代码维护性
  2. 提升开发效率,支持并行开发
  3. 优化编译速度
  4. 增强扩展性和灵活性
  5. 支持模块独立调试和测试
  6. 提升代码复用性

什么是模块化,组件化,插件化?

  1. 模块化(Modularization)

模块化是指将应用程序分解为多个功能模块,每个模块可以独立开发、测试和复用。这些模块通常会有各自的职责,比如“用户模块”、“支付模块”、“商品模块”等。模块化的目标是提升代码的可管理性和复用性。

常见实现

可以使用Gradle的多模块项目来实现模块化,每个模块可以是library或者feature module,各模块依赖于主应用模块(app module)或其他模块。

  1. 组件化(Componentization)

组件化是一种更高级的模块化,强调将应用拆分为多个独立的功能组件(组件可以理解为功能更聚焦的模块),这些组件可以独立运行、开发和测试,且具有更高的解耦性。组件化的目标不仅是分离代码,还能实现不同功能模块的相对独立和复用,比如组件可以在多个项目中共享。

  1. 插件化
  • 单位:插件(APK),通常是可以作为独立应用存在的模块。
  • 目标:通过将应用拆分成多个独立的APK文件,使得功能模块可以独立加载和卸载,支持热插拔和热更新。
  • 特点:
    • 插件化强调模块的完全独立性,每个插件都可以是一个完整的APK,可以在不重启主应用的情况下动态加载。
    • 适合需要动态加载和更新的场景,比如微信的“朋友圈”功能,可以单独作为一个APK文件动态下载、更新,并在主应用中加载。
    • 可以通过动态下载、热更新的方式,大大增强了应用的灵活性和扩展性。
特点模块化组件化插件化
侧重点项目内的业务功能划分功能的复用性和低耦合性功能的动态加载和热更新
耦合度较低更低极低(插件可以完全独立运行)
独立性模块之间不可独立运行每个组件通常可以独立运行每个插件通常是一个独立的APK
应用场景项目内部功能划分可在不同项目中共享的功能支持动态加载、热更新的应用场景
适用项目规模中小型项目大型项目或需要高复用性需求的项目需要频繁更新和动态扩展的大型项目
构建和调试依赖主应用,通常无法独立构建和调试可单独调试,利于开发效率插件可以独立构建和调试,支持动态加载
动态更新不支持动态更新不支持动态更新支持动态下载、热更新

实现要解决的问题

  1. 如何将项目工程进行分层?
  2. 如何实现单独运行调试?
  3. 组件间如何实现页面的跳转?
  4. 组件间如何实现组件间通信/方法调用?
  5. 组件的生命周期

组件分层

image-20241107104838442

创建module

业务组件层:

image-20241107165424455

image-20241107170911383

业务组件层和功能组件层

image-20241107171529946

image-20241107172133419

组件单独调试

在 Android 开发中,Gradle 插件可以配置不同类型的工程,主要有以下三种:

  1. App 插件 (com.android.application):

    • 用于创建可独立运行的 Android 应用程序。
    • 它将构建完整的 APK 文件,可以直接部署到设备或应用商店中。
    • 适合需要打包发布的应用开发项目。
  2. Library 插件 (com.android.library):

    • 用于构建 Android 库模块。
    • 构建输出是 AAR 文件(Android Archive),包含资源、代码等,但不能直接运行。
    • 适用于开发通用模块(如 UI 组件库、数据模块等),可在不同的 App 项目中复用。
  3. Test 插件 (com.android.test):

    • 专门用于构建测试模块,可以运行独立的测试代码。
    • 适合构建单独的测试模块,用于 UI 测试或集成测试等。
    • 一般情况下,这个插件主要在大型项目中使用,以实现独立的测试逻辑

配置组件工程类型

通过修改依赖的插件来配置工程的类型,让模块可以被单独调试,也可以被

在project的gradle.properties中加入

isRunAlone = true

为真时表示各个模块可以独立运行

然后在需要单独测试的模块中加入判断

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

image-20241108221629578

这里成功运行了模块main的界面

配置组件ApplicationId和AndroidManifest文件

在组件单独调试和集成调试的不同模式下,自动调整一些配置,防止Application ID 冲突或者启动页冲突

1.配置AndroidManifest

image-20241108222725460

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

    <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.NeteaseMusiccomponet">
        <activity
            android:name=".MainActivity">
        </activity>
    </application>

</manifest>

删掉

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

2.配置ApplicationId和AndroidManifest

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

android {
    namespace 'com.example.main'
    compileSdk 34

    defaultConfig {
        if (isRunAlone.toBoolean()) {
            applicationId "com.example.main"
        }
        minSdk 29
        targetSdk 34
        versionCode 1
        versionName "1.0"

        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    }

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

   ...
}
...

加上如下代码,表示单独调试时添加applicationId,以及集成调试时使用的配置文件

if (isRunAlone.toBoolean()) {
    applicationId "com.example.main"
}
和
sourceSets{
    main{
        if(isRunAlone.toBoolean()){
            manifest.srcFile'src/main/debugmanifest/AndroidManifest.xml'
        }else {
            manifest.srcFile'src/main/AndroidManifest.xml'
        }
    }
}

这样就实现了需要集成调试将gradle.properties修改为false,可以正常运行



感谢您的阅读
如有错误烦请指正


参考:

  1. Android 组件化最佳实践在项目的开发过程中,随着开发人员的增多及功能的增加,如果提前没有使用合理的开发架构,那么代 - 掘金 (juejin.cn)
  2. Android组件化开发实践(二):组件化架构设计 - 简书 (jianshu.com)
;