handleBindApplication
handleBindApplication() 是应用进程从“已向 AMS attach 的空壳”进入“包代码可以运行”的核心入口。AMS 通过 ApplicationThread Binder 传入 AppBindData,ActivityThread 主线程依次安装 compat、进程身份、资源配置、LoadedApk、网络安全、Instrumentation,创建 Application,先安装 ContentProvider,再调用 Application.onCreate(),最后 finishAttachApplication() 通知 AMS 应用绑定完成。
1. Bind消息入口
源码文件:frameworks/base/core/java/android/app/ActivityThread.java
private void handleBindApplication(AppBindData data) {
mDdmSyncStageUpdater.next(Stage.Bind);
VMRuntime.registerSensitiveThread();
Process.setStartTimes(
SystemClock.elapsedRealtime(),
SystemClock.uptimeMillis(),
data.startRequestedElapsedTime,
data.startRequestedUptime);
AppCompatCallbacks.install(
data.disabledCompatChanges,
data.enabledCompatChanges,
data.mLoggableCompatChanges,
data.mLogChangeChecksToStatsD,
data.appInfo.targetSdkVersion);bind 在 ActivityThread 主 Handler 消费,先记录 DDM stage、注册敏感线程、保存 AMS 请求时间并安装完整 compat 数据。这里覆盖 RuntimeInit 的早期 compat 基线,因为 AMS 已提供包和进程级完整配置。
2. 进程身份与运行时
mBoundApplication = data;
mConfigurationController.setConfiguration(data.config);
mCompatibilityInfo = data.compatInfo;
Process.setArgV0(data.processName);
DdmHandleAppName.setAppName(
data.processName,
data.appInfo.packageName,
UserHandle.myUserId());
VMRuntime.setProcessPackageName(
data.appInfo.packageName);
VMRuntime.setProcessDataDirectory(
data.appInfo.dataDir);进程名从 <pre-initialized> 切到真实 processName;VMRuntime 获得 package 和 data directory,用于 profile/cache。该顺序必须在加载应用代码前完成,否则静态初始化生成的缓存和诊断信息会归属错误进程。
3. 资源与LoadedApk
synchronized (mResourcesManager) {
mResourcesManager.applyConfigurationToResources(
data.config, data.compatInfo);
mCurDefaultDisplayDpi = data.config.densityDpi;
mConfigurationController.applyCompatConfiguration();
}
data.info = getPackageInfo(
data.appInfo, mCompatibilityInfo,
null, false,
true /*includeCode*/,
false /*registerPackage*/,
isSdkSandbox);先把 AMS 提供的最新 Configuration 应用到 ResourcesManager,再创建 LoadedApk。includeCode=true 允许加载 APK 代码和 classloader;SDK sandbox 还会设置独立 storage。LoadedApk 是 Application、组件和资源的包级 owner。
4. 网络与安全前置
ContextImpl appContext = ContextImpl.createAppContext(
this, data.info);
NetworkSecurityConfigProvider.install(appContext);
if (!Process.isIsolated()) {
TrafficStats.init(appContext);
}
if (!Process.isIsolated()) {
setupGraphicsSupport(appContext);
} else {
HardwareRenderer.setIsolatedProcess(true);
}Network Security Config 必须在应用代码创建 TLS 对象前安装;isolated process 不访问相关网络服务。graphics support 同样按 isolated 状态分流。appContext 已存在,但 Application 尚未创建。
5. Instrumentation
InstrumentationInfo ii;
if (data.instrumentationName != null) {
ii = prepareInstrumentation(data);
} else {
ii = null;
}
if (ii != null) {
initInstrumentation(ii, data, appContext);
} else {
mInstrumentation = new Instrumentation();
mInstrumentation.basicInit(this);
}Instrumentation 会影响 classloader 和 Application 创建,所以必须先准备。默认路径创建基础 Instrumentation;测试路径加载 instrumentation APK、runner 和参数。失败时 Application 未创建,后续 Provider/onCreate 不执行。
6. Application顺序
源码文件:frameworks/base/core/java/android/app/ActivityThread.java
Application app = data.info.makeApplicationInner(
data.restrictedBackupMode, null);
mInitialApplication = app;
if (!data.restrictedBackupMode
&& !ArrayUtils.isEmpty(data.providers)) {
installContentProviders(app, data.providers);
}
mInstrumentation.onCreate(
data.instrumentationArgs);
long timestampApplicationOnCreateNs =
SystemClock.uptimeNanos();
mInstrumentation.callApplicationOnCreate(app);Application 先构造并保存为 initial application;普通模式随后安装 ContentProvider,之后才执行 Instrumentation.onCreate 和 Application.onCreate。Provider 提前是 Android 启动语义的重要边界:Provider 的 onCreate() 可以早于 Application.onCreate 被外部/框架使用。restricted backup mode 使用基础 Application 并跳过 Provider,避免加载自定义应用逻辑。
7. StrictMode与异常
源码文件:frameworks/base/core/java/android/app/ActivityThread.java
StrictMode.ThreadPolicy savedPolicy =
StrictMode.allowThreadDiskWrites();
try {
app = data.info.makeApplicationInner(...);
...
mInstrumentation.callApplicationOnCreate(app);
} finally {
if (data.appInfo.targetSdkVersion
< Build.VERSION_CODES.O_MR1
|| StrictMode.getThreadPolicy()
.equals(writesAllowedPolicy)) {
StrictMode.setThreadPolicy(savedPolicy);
}
}应用/Provider 初始化允许主线程磁盘写入,因为加载 APK、资源和 provider 通常需要 I/O;finally 按 target SDK/应用是否自行修改 policy 决定恢复。Application.onCreate 异常先交给 Instrumentation.onException;未处理时包装为“Unable to create application”并终止绑定。
8. 完成通知
mgr.finishAttachApplication(
mStartSeq,
timestampApplicationOnCreateNs);
Binder.setTransactionCallback(
(pid, code, flags, err) ->
mgr.frozenBinderTransactionDetected(
pid, code, flags, err));只有 Application.onCreate 成功后才调用 finishAttachApplication(),AMS 据此完成 startSeq 对应的进程绑定状态。随后安装 Binder transaction error callback。进程已经 attach AMS 不代表 bind 完成,finishAttach 才是应用初始化成功的重要服务端信号。
9. 失败与状态边界
- AppBindData 已收到:不代表 LoadedApk/Application 已创建;
- LoadedApk 已创建:不代表 Provider/Application.onCreate 成功;
- Provider 已安装:Application.onCreate 可能随后失败;
- Application.onCreate 成功:仍需 finishAttachApplication 通知 AMS;
- instrumentation 异常:可在 Application 之前终止;
- ConnectivityService 为空:记录 WTF 并使用空 proxy 配置;
- isolated process:跳过 TrafficStats/普通 graphics 网络路径。
10. 导航与后续
# bind 主线、compat、进程名、资源、LoadedApk 和 Application。
rg -n "handleBindApplication|AppCompatCallbacks|setArgV0|getPackageInfo|createAppContext|prepareInstrumentation|makeApplicationInner|installContentProviders|callApplicationOnCreate|finishAttachApplication" \
frameworks/base/core/java/android/app/ActivityThread.java
# AMS 发出 bindApplication 和 finishAttach 的服务端消费。
rg -n "bindApplication\(|finishAttachApplication|AppBindData|startSeq" \
frameworks/base/services/core/java/com/android/server/am \
frameworks/base/core/java/android/app/ActivityThread.java下一篇将专门分析 Application.onCreate() 前后的 Provider、Instrumentation 和进程 ready 语义;不会重复整个 bind 主线。
