一 概述
1 2
| 以下是关于 Android 架构相关面试题:组件化与插件化 的全面整理, 适用于面试准备与深入理解架构设计
|
二 什么是组件化与插件化?
1 2 3 4 5 6 7
| 1.组件化(Componentization) -是将项目拆分成多个功能模块(组件),解耦开发、独立编译、独立运行、降低维护成本。 -如:app、login、home、user、network、common 等模块。
2.插件化(Pluginization) 是将部分功能封装为“插件”,主工程运行时动态加载插件,不需要重新打包主工程, 适用于大体积、可扩展的 App(如:支付宝、滴滴、微博等)。
|
三 面试题解答(仅供参考)
2.1 为什么要进行组件化开发?
1 2
| 解决 App 体积大、协作难、耦合重、编译慢的问题。 组件化可以按业务模块拆分,做到“分而治之”。
|
2.2 如何实现组件化?核心思路是什么?
1 2 3 4 5
| 核心是 将业务拆分为多个 module,每个模块独立编译/运行/测试/开发,最终在主 App 汇总打包。
-公共库(common):提供工具类、UI 基类、路由等。 -业务模块:如 login、home、user,具备独立运行能力。 -主工程 app:仅负责壳聚合。
|
2.3 组件如何通信?如何解耦依赖?
有三种常用解耦方式:
通信方式 |
原理 |
使用场景 |
接口 + SPI |
Java SPI + 反射加载 |
服务注册、初始化 |
路由框架(ARouter) |
路由映射 + 注解 |
页面/服务跳转 |
事件总线(LiveData/EventBus) |
发布订阅模型 |
状态或事件传递 |
说明:SPI(Service Provider Interface)是 Java 提供的一种服务发现机制,允许模块在运行时动态加载和扩展实现类
2.4 怎么实现组件的单独运行?
1 2 3 4
| 每个模块配置 isRunAlone = true 时独立运行,Manifest 中配置 launcher Activity; 主工程聚合时排除 isRunAlone 模块的入口 Activity。
通常使用 Gradle DSL + build flavor 实现。
|
2.5 插件化与组件化的区别?
对比项 |
插件化 |
组件化 |
加载方式 |
动态加载 |
编译期合并 |
模块独立性 |
插件无需在主工程编译时参与编译 |
编译期依赖主工程 |
使用场景 |
大型 App 功能扩展、动态更新 |
日常开发分模块协作 |
框架依赖 |
需要框架支持,如 Shadow、RePlugin |
无需框架支持,原生 Gradle 即可 |
2.6 插件化如何实现动态加载?
1 2 3 4
| 主要分为三步: 1.ClassLoader 替换:通过 DexClassLoader 加载插件 dex。 2.Resource 替换:替换 Resources,加载插件的资源。 3.Activity 启动绕过 AMS 校验:通过占坑 Activity 或 hook Instrumentation 实现插件页面跳转。
|
2.7 插件化框架有哪些?推荐哪个?
插件框架 |
特点说明 |
Shadow(腾讯) |
纯插件架构,无需修改宿主 |
RePlugin(360) |
支持动态安装,框架庞大,学习曲线陡峭 |
DroidPlugin(阿里) |
支持多插件,难维护,已较少维护 |
2.8 插件如何避免资源 id 冲突?
1 2
| 插件打包时使用 aapt2 生成独立 R 文件, 并通过资源隔离加载插件资源,使用 ResourcePrefix 或资源映射表。
|
2.9 如何高分回答“组件化和插件化”?
1 2 3
| 我们项目采用组件化架构,使用 Gradle 多模块 + ARouter 实现模块间解耦; 每个模块支持独立运行,方便多人协作、快速开发和测试。 同时我们评估过插件化框架,如 Shadow,可用于插件功能动态下发,避免全量更新。
|
三 参考