Skip to content

架构设计 / Gradle / 工程化 — 知识详解

更新: 5/15/2026 字数: 0 字 时长: 0 分钟

组件化、路由与依赖注入内容较多,已拆分为独立文件:

  • component-router-hilt-deep.md — 组件化架构设计(分层/独立运行/通信方案)、ARouter 源码分析(APT/路由查找/拦截器/降级)、Hilt 依赖注入(Module/Scope/Qualifier/编译期原理)

1. 架构模式

1.1 MVC

View(XML 布局)→ Controller(Activity)→ Model(数据)

问题:Activity 同时承担 Controller 和部分 View 的职责,变得臃肿("God Activity")。

1.2 MVP

View(Activity/Fragment)←→ Presenter ←→ Model
  • View 和 Presenter 通过接口通信
  • Presenter 不持有 Android 组件引用(可单元测试)
  • 问题:接口爆炸、Presenter 可能臃肿、生命周期管理复杂

1.3 MVVM

View ←(observe)← ViewModel ←→ Repository
  • View 通过 LiveData/StateFlow 观察 ViewModel
  • ViewModel 不持有 View 引用
  • 数据驱动 UI,配置变更时 ViewModel 存活

1.4 MVI

View →(Intent)→ ViewModel →(State)→ View
  • 单向数据流
  • 不可变状态
  • 可预测、可追溯

1.5 Clean Architecture

┌─────────────────────────────────┐
│  Presentation Layer             │  ViewModel, UI
├─────────────────────────────────┤
│  Domain Layer                   │  UseCase, Entity, Repository接口
├─────────────────────────────────┤
│  Data Layer                     │  Repository实现, DataSource, API, DB
└─────────────────────────────────┘

依赖规则:外层依赖内层,内层不知道外层。Domain 层是纯 Kotlin,不依赖 Android 框架。

kotlin
// Domain 层
class GetUserUseCase(private val userRepository: UserRepository) {
    suspend operator fun invoke(userId: Int): Result<User> {
        return userRepository.getUser(userId)
    }
}

// Data 层
class UserRepositoryImpl(
    private val api: ApiService,
    private val dao: UserDao
) : UserRepository {
    override suspend fun getUser(userId: Int): Result<User> {
        return try {
            val user = api.getUser(userId)
            dao.insert(user)
            Result.success(user)
        } catch (e: Exception) {
            val cached = dao.getUser(userId)
            if (cached != null) Result.success(cached)
            else Result.failure(e)
        }
    }
}

2. 设计模式在 Android 中的应用

2.1 单例模式

  • Application 全局单例
  • Room Database
  • Retrofit 实例

2.2 工厂模式

  • BitmapFactory.decodeResource/decodeFile
  • LayoutInflater.inflate
  • Fragment.newInstance(静态工厂方法)

2.3 观察者模式

  • LiveData / Flow
  • BroadcastReceiver
  • OnClickListener
  • Lifecycle Observer

2.4 责任链模式

  • OkHttp 拦截器链
  • View 事件分发(ViewGroup → View)

2.5 代理模式

  • Retrofit 动态代理
  • Binder 的 Stub/Proxy
  • AIDL 生成的代理类

2.6 建造者模式

  • AlertDialog.Builder
  • OkHttpClient.Builder
  • Retrofit.Builder
  • Notification.Builder

2.7 策略模式

  • RecyclerView.LayoutManager(LinearLayout/Grid/StaggeredGrid)
  • Interpolator(线性/加速/减速)

2.8 模板方法模式

  • Activity 生命周期(onCreate/onStart/onResume 是模板方法)
  • AsyncTask(doInBackground/onPostExecute)
  • BaseAdapter(getView)

3. 组件化架构

3.1 为什么组件化?

单体应用的问题:

  • 编译慢(全量编译)
  • 代码耦合严重
  • 多团队协作困难
  • 无法独立测试

3.2 组件化架构

┌──────────────────────────────────┐
│            App Shell             │  壳工程,组装各组件
├──────┬──────┬──────┬────────────┤
│ 首页  │ 播放  │ 我的  │ 消息       │  业务组件(可独立运行)
├──────┴──────┴──────┴────────────┤
│          公共组件层               │  网络、图片、日志、埋点
├──────────────────────────────────┤
│          基础库层                 │  工具类、UI 组件、路由
└──────────────────────────────────┘

3.3 路由

组件间不能直接依赖,通过路由框架跳转:

kotlin
// 注册(注解)
@Route(path = "/video/detail")
class VideoDetailActivity : AppCompatActivity()

// 跳转
ARouter.getInstance()
    .build("/video/detail")
    .withLong("videoId", 12345)
    .navigation()

ARouter 原理:

  1. 编译期 APT 扫描 @Route 注解,生成路由表(path → Class 映射)
  2. 运行时根据 path 查找目标 Class
  3. 支持拦截器(登录检查、降级)

3.4 组件间通信

kotlin
// 1. 接口下沉 + SPI
// 公共层定义接口
interface IUserService {
    fun getUserName(): String
}

// 用户组件实现
class UserServiceImpl : IUserService {
    override fun getUserName() = "张三"
}

// 其他组件通过 ServiceLoader 或 ARouter 获取实现
val userService = ARouter.getInstance().navigation(IUserService::class.java)

// 2. EventBus / LiveDataBus
// 3. ContentProvider

3.5 依赖注入

Hilt(基于 Dagger):

kotlin
@HiltAndroidApp
class MyApp : Application()

@AndroidEntryPoint
class MainActivity : AppCompatActivity() {
    @Inject lateinit var repository: UserRepository
}

@Module
@InstallIn(SingletonComponent::class)
object AppModule {
    @Provides
    @Singleton
    fun provideUserRepository(api: ApiService, dao: UserDao): UserRepository {
        return UserRepositoryImpl(api, dao)
    }
}

4. Gradle 构建系统

4.1 构建生命周期

初始化阶段(Initialization)
  → 执行 settings.gradle,确定参与构建的项目
配置阶段(Configuration)
  → 执行所有 build.gradle,构建 Task DAG
执行阶段(Execution)
  → 按 DAG 顺序执行 Task

4.2 Task DAG

:app:preBuild
  → :app:compileDebugKotlin
    → :app:mergeDebugResources
      → :app:packageDebug
        → :app:assembleDebug

Task 之间通过 dependsOnmustRunAfter 等建立依赖关系,Gradle 自动拓扑排序并行执行无依赖的 Task。

4.3 自定义 Plugin

kotlin
class MyPlugin : Plugin<Project> {
    override fun apply(project: Project) {
        project.tasks.register("myTask") {
            doLast {
                println("Hello from custom plugin!")
            }
        }
    }
}

4.4 依赖管理

kotlin
// Version Catalog (libs.versions.toml)
[versions]
kotlin = "1.9.0"
compose = "1.5.0"

[libraries]
kotlin-stdlib = { module = "org.jetbrains.kotlin:kotlin-stdlib", version.ref = "kotlin" }

[plugins]
kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }

依赖冲突解决:

  • implementation:编译和运行时可见,不传递给消费者
  • api:编译和运行时可见,传递给消费者
  • compileOnly:只在编译时可见
  • 版本冲突:Gradle 默认选择最高版本,可用 forceexcluderesolutionStrategy 控制

4.5 构建优化

  • 开启 Gradle 守护进程和并行构建
  • 使用 Build Cache
  • 合理使用 implementation 减少重编译范围
  • 避免在配置阶段执行耗时操作
  • 使用 Configuration Cache(Gradle 7+)

5. CI/CD 与质量门禁

  • 代码检查:Lint、Detekt(Kotlin)、ktlint
  • 单元测试:JUnit + Mockk/Mockito
  • UI 测试:Espresso、Compose Testing
  • 代码覆盖率:JaCoCo
  • 自动化构建:Jenkins / GitHub Actions / GitLab CI
  • 质量门禁:PR 必须通过 Lint + 单元测试 + 代码审查