Android 的多进程机制 (Android Multi-Process Model)
1. 核心概念
独立进程会创建新的虚拟机:每个进程有独立的 ART/Dalvik 虚拟机。
但共享同一个 APK:所有代码、资源都从同一个 APK 加载。
Application 多实例:每个进程都会新建一个
Application
实例并执行onCreate()
。
✅ 一句话总结:
在 Android 中,每个进程都有独立的虚拟机和
Application
实例,但它们共享同一个 APK 文件的代码与资源。
2. 虚拟机与 Application 行为
同一个 APK → 全部进程使用相同的
.QMaxApplication
类。不同进程 → 系统会为每个进程创建新的虚拟机和新的
Application
实例。Application.onCreate() → 每个进程都会调用一次,导致可能 重复初始化。
3. 实例对比
主进程 (com.robot.qmaxsysapp)
├── 虚拟机1
├── QMaxApplication 实例1
└── MainActivity
独立进程 (com.robot.qmaxsysapp:voice_command_service)
├── 虚拟机2 ← 新的虚拟机
├── QMaxApplication 实例2 ← 新的实例
└── VoiceCommandService
4. 配置示例
<application android:name=".QMaxApplication"><!-- 主进程 --><activity android:name=".MainActivity" /><!-- 独立进程 --><serviceandroid:name="com.robot.mod_voicecommand.service.VoiceCommandService"android:process=":voice_command_service" />
</application>
5. 问题场景
主进程和独立进程都调用了 QMaxApplication.onCreate()
:
- 主进程初始化模块 → TCP 服务占用端口 10110。
- 独立进程再次初始化 → 冲突!
BindException: Address already in use
(端口被占用)
ClassCastException: BinderProxy cannot be cast...
(跨进程 Binder 错误)
6. 解决方案
根据进程名,区分初始化逻辑:
override fun onCreate() {super.onCreate()val currentProcess = getCurrentProcessName()if (isMainProcess(currentProcess)) {// 主进程:完整初始化initModules()} else {// 独立进程:只做基础初始化initBasicComponentsOnly()}
}
主进程 → 初始化所有业务模块 (TCP/WebSocket/业务逻辑)。
独立进程 → 仅初始化基础组件 (日志、MMKV、CrashHandler)。
7. 核心思想
👉 多进程环境下,Application.onCreate() 会被调用多次。
要避免重复初始化,必须 按进程类型做有选择的初始化。
主进程:完整初始化(TCP 服务、模块加载)。
独立进程:最小化初始化(仅运行独立服务)。
⚡ 这就是 Android 多进程机制下 Application 重复初始化的问题与解决方案。