Android 启动过程Activity 启动源码分析 ( ActivityThread 流程分析 一 )
Posted 韩曙亮
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android 启动过程Activity 启动源码分析 ( ActivityThread 流程分析 一 )相关的知识,希望对你有一定的参考价值。
文章目录
- 一、ActivityThread 主函数启动
- 二、ActivityThread 绑定 ApplicationThread
- 三、AMS attachApplication -> attachApplicationLocked 绑定 ApplicationThread
- 四、ApplicationThread.bindApplication 绑定 ApplicationThread
- 五、ActivityThread.H 处理 BIND_APPLICATION 消息
- 六、ActivityThread.handleBindApplication 处理绑定问题
- 七、LoadedApk.makeApplication 创建 Application 对象
- 八、Instrumentation.newApplication 创建 Application 对象
- 九、AppComponentFactory.instantiateApplicationCompat 创建 Application 对象
一、ActivityThread 主函数启动
ActivityThread
是应用的主线程 , 从 main
函数开始执行 ;
Looper.prepareMainLooper()
将主线程设置为 Looper 线程 , 开启 Looper , 用于配合 H 处理消息 ;
thread.attach(false, startSeq)
绑定 ActivityThread
;
在方法最后 Looper.loop();
开始无限循环 , 处理 Handler 消息 ;
/**
* 管理应用程序进程中主线程的执行、调度和执行活动、广播以及活动管理器请求的其他操作。
*
* {@hide}
*/
public final class ActivityThread extends ClientTransactionHandler {
public static void main(String[] args) {
// 将主线程设置为 Looper 线程 , 开启 Looper , 用于配合 H 处理消息
Looper.prepareMainLooper();
// 创建 ActivityThread 实例对象
ActivityThread thread = new ActivityThread();
// 绑定
thread.attach(false, startSeq);
// 开始无限循环 , 处理 Handler 消息
Looper.loop();
throw new RuntimeException("Main thread loop unexpectedly exited");
}
}
完整代码参考 /frameworks/base/core/java/android/app/ActivityThread.java
二、ActivityThread 绑定 ApplicationThread
ActivityThread
中的 void attach(boolean system, long startSeq)
方法 , 主要是通过 Binder 机制获取 AMS , 并调用 AMS 的 attachApplication 方法 , 为 ActivityThread 绑定 ApplicationThread ;
/**
* 管理应用程序进程中主线程的执行、调度和执行活动、广播以及活动管理器请求的其他操作。
*
* {@hide}
*/
public final class ActivityThread extends ClientTransactionHandler {
private void attach(boolean system, long startSeq) {
sCurrentActivityThread = this;
mSystemThread = system;
if (!system) {
RuntimeInit.setApplicationObject(mAppThread.asBinder());
// 通过 Binder 机制获取 AMS
final IActivityManager mgr = ActivityManager.getService();
try {
// 调用 AMS 的 attachApplication 方法 , 为 ActivityThread 绑定 ApplicationThread
mgr.attachApplication(mAppThread, startSeq);
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
}
}
}
完整代码参考 /frameworks/base/core/java/android/app/ActivityThread.java
三、AMS attachApplication -> attachApplicationLocked 绑定 ApplicationThread
在 AMS 中的 attachApplication
方法中 , 调用了 attachApplicationLocked
方法 ,
在 attachApplicationLocked
方法中 , 有调用了 ActivityThread 的 bindApplication
方法 , 为 ActivityThread
绑定了 ApplicationThread
;
public class ActivityManagerService extends IActivityManager.Stub
implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
@Override
public final void attachApplication(IApplicationThread thread) {
synchronized (this) {
int callingPid = Binder.getCallingPid();
final long origId = Binder.clearCallingIdentity();
attachApplicationLocked(thread, callingPid);
Binder.restoreCallingIdentity(origId);
}
}
// 为 ApplicationThread 绑定 Application 主方法
private final boolean attachApplicationLocked(IApplicationThread thread,
int pid) {
try {
checkTime(startTime, "attachApplicationLocked: immediately before bindApplication");
mStackSupervisor.mActivityMetricsLogger.notifyBindApplication(app);
// 在此处为 ActivityThread 绑定 Application , 此时又回到 ActivityThread
if (app.instr != null) {
thread.bindApplication(processName, appInfo, providers,
app.instr.mClass,
profilerInfo, app.instr.mArguments,
app.instr.mWatcher,
app.instr.mUiAutomationConnection, testMode,
mBinderTransactionTrackingEnabled, enableTrackAllocation,
isRestrictedBackupMode || !normalMode, app.persistent,
new Configuration(getGlobalConfiguration()), app.compat,
getCommonServicesLocked(app.isolated),
mCoreSettingsObserver.getCoreSettingsLocked(),
buildSerial);
} else {
thread.bindApplication(processName, appInfo, providers, null, profilerInfo,
null, null, null, testMode,
mBinderTransactionTrackingEnabled, enableTrackAllocation,
isRestrictedBackupMode || !normalMode, app.persistent,
new Configuration(getGlobalConfiguration()), app.compat,
getCommonServicesLocked(app.isolated),
mCoreSettingsObserver.getCoreSettingsLocked(),
buildSerial);
}
} catch (Exception e) {
}
return true;
}
}
ActivityManagerService 完整源码参考 : frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
四、ApplicationThread.bindApplication 绑定 ApplicationThread
再次回到 ActivityThread
内部类 ApplicationThread
中 , 调用 ApplicationThread
类的 bindApplication
方法 , 即可为 ActivityThread 绑定 ApplicationThread , 在所有数据就位后 , 发送了一个 H.BIND_APPLICATION 消息 ;
/**
* 管理应用程序进程中主线程的执行、调度和执行活动、广播以及活动管理器请求的其他操作。
*
* {@hide}
*/
public final class ActivityThread extends ClientTransactionHandler {
private class ApplicationThread extends IApplicationThread.Stub {
// 为 ActivityThread 绑定 Application
public final void bindApplication(String processName, ApplicationInfo appInfo,
List<ProviderInfo> providers, ComponentName instrumentationName,
ProfilerInfo profilerInfo, Bundle instrumentationArgs,
IInstrumentationWatcher instrumentationWatcher,
IUiAutomationConnection instrumentationUiConnection, int debugMode,
boolean enableBinderTracking, boolean trackAllocation,
boolean isRestrictedBackupMode, boolean persistent, Configuration config,
CompatibilityInfo compatInfo, Map services, Bundle coreSettings,
String buildSerial, boolean autofillCompatibilityEnabled) {
// 此处在所有数据就位后 , 发送了一个 H.BIND_APPLICATION 消息
sendMessage(H.BIND_APPLICATION, data);
}
}
}
完整代码参考 /frameworks/base/core/java/android/app/ActivityThread.java
五、ActivityThread.H 处理 BIND_APPLICATION 消息
在 ActivityThread.ApplicationThread.bindApplication
中 , 发送了一条 BIND_APPLICATION
消息 ,
110
110
110 ;
在 ActivityThread.H
中的 handleMessage
方法中 , 处理
110
110
110 事件的分支中, 调用了 handleBindApplication
方法 , 处理绑定 ApplicationThread
相关逻辑 ;
/**
* 管理应用程序进程中主线程的执行、调度和执行活动、广播以及活动管理器请求的其他操作。
*
* {@hide}
*/
public final class ActivityThread extends ClientTransactionHandler {
class H extends Handler {
public static final int BIND_APPLICATION = 110;
public void handleMessage(Message msg) {
if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
switch (msg.what) {
case BIND_APPLICATION:
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "bindApplication");
AppBindData data = (AppBindData)msg.obj;
// 处理绑定 Application 相关逻辑
handleBindApplication(data);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
break;
}
Object obj = msg.obj;
if (obj instanceof SomeArgs) {
((SomeArgs) obj).recycle();
}
}
}
}
完整代码参考 /frameworks/base/core/java/android/app/ActivityThread.java
六、ActivityThread.handleBindApplication 处理绑定问题
在 ActivityThread.handleBindApplication
方法中 , 通过调用 data.info.makeApplication(data.restrictedBackupMode, null)
方法 , 创建 Application 实例对象 ;
data.info
是 LoadedApk
类型 ;
/**
* 管理应用程序进程中主线程的执行、调度和执行活动、广播以及活动管理器请求的其他操作。
*
* {@hide}
*/
public final class ActivityThread extends ClientTransactionHandler {
private void handleBindApplication(AppBindData data) {
// 将UI线程注册为运行时的敏感线程。
VMRuntime.registerSensitiveThread();
if (data.trackAllocation) {
DdmVmInternal.enableRecentAllocations(true);
}
// 记录进程开始时间
Process.setStartTimes(SystemClock.elapsedRealtime(), SystemClock.uptimeMillis());
// 允许在应用程序和提供程序安装期间访问磁盘。
// 这可能会阻止处理有序的广播,但稍后的处理可能最终会执行相同的磁盘访问。
Application app;
final StrictMode.ThreadPolicy savedPolicy = StrictMode.allowThreadDiskWrites();
final StrictMode.ThreadPolicy writesAllowedPolicy = StrictMode.getThreadPolicy();
try {
// 如果要启动应用程序进行完全备份或恢复,请使用基本应用程序类在受限环境中启动。
app = data.info.makeApplication(data.restrictedBackupMode, null);
// Propagate autofill compat state
app.setAutofillCompatibilityEnabled(data.autofillCompatibilityEnabled);
mInitialApplication = app;
}
}
}
完整代码参考 /frameworks/base/core/java/android/app/ActivityThread.java
七、LoadedApk.makeApplication 创建 Application 对象
调用 LoadedApk
的 makeApplication
方法 , 创建 Application
实例 , 在该方法中通过调用 Instrumentation
的 newApplication
方法 , 创建 Application
实例对象
/**
* 本地状态维护了当前加载的.apk.
* Local state maintained about a currently loaded .apk.
* @hide
*/
public final class LoadedApk {
// 创建 Application 实例对象
public Application makeApplication(boolean forceDefaultAppClass,
Instrumentation instrumentation) {
// 如果当前存在 Application , 直接返回
if (mApplication != null) {
return mApplication;
}
try {
ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);
// 通过调用 Instrumentation 的 newApplication 方法 , 创建 Application 实例对象
app = mActivityThread.mInstrumentation.newApplication(
cl, appClass, appContext);
appContext.setOuterContext(app);
} catch (Exception e) {
}
mActivityThread.mAllApplications.add(app);
mApplication = app;
return app;
}
}
完整代码参考 /frameworks/base/core/java/android/app/LoadedApk.java ;
八、Instrumentation.newApplication 创建 Application 对象
在 LoadedApk
的 makeApplication
方法 中 , 调用了 Instrumentation
的 newApplication
方法创建 Application
实例对象 ;
/**
* 用于实现应用程序检测代码的基类。
* 当在启用检测的情况下运行时,该类将在任何应用程序代码之前为您实例化,
* 从而允许您监视系统与应用程序之间的所有交互。
* 通过androidManifest.xml的&lt;仪器仪表&gt;标签。
*/
public class Instrumentation {
/**
* 执行进程{@link Application}对象的实例化。默认实现提供正常的系统行为。
*
* @param cl 用来实例化对象的类加载器。
* @param className 实现应用程序对象的类的名称。
* @param context 用于初始化应用程序的上下文
*
* @return 新实例化的应用程序对象。
*/
public Application newApplication(ClassLoader cl, String className, Context context)
throws InstantiationException, IllegalAccessException,
ClassNotFoundException {
Application app = getFactory(context.getPackageName())
.instantiateApplication(cl, className);
app.attach(context);
return app;
}
}
完整代码参考 /frameworks/base/core/java/android/app/Instrumentation.java ;
九、AppComponentFactory.instantiateApplicationCompat 创建 Application 对象
在 Instrumentation
的 newApplication
方法中 , 调用了 AppComponentFactory
的 instantiateApplicationCompat
方法 , 创建 Application
, (Application) cl.loadClass(className).getDeclaredConstructor().newInstance();
, 此处通过反射创建 Application
实例对象 ;
/**
* 使用androidx库的{@link android.app.AppComponentFactory}版本。
*
* 注意:这只适用于API 28+,不支持AppComponentFactory功能。
*/
@RequiresApi(28)
public class AppComponentFactory extends android.app.AppComponentFactory {
/**
* 允许应用程序重写应用程序对象的创建。这可以用于对这些类执行依赖项注入或类装入器更改等操作。
* <p>
* 此方法仅用于提供用于实例化的挂钩。它不提供对应用程序对象的早期访问。
* 返回的对象尚未初始化为上下文,不应用于与其他android API交互。
*
* @param cl 用于实例化的默认类加载器。
* @param className 要实例化的类。
*/
public @NonNull Application instantiateApplicationCompat(@NonNull ClassLoader cl,
@NonNull String className)
throws InstantiationException, IllegalAccessException, ClassNotFoundException {
try {
return (Application) cl.loadClass(className).getDeclaredConstructor().newInstance();
} catch (InvocationTargetException | NoSuchMethodException e) {
throw new RuntimeException("Couldn't call constructor", e);
}
}
}
完整代码参考 /frameworks/support/compat/src/main/java/androidx/core/app/AppComponentFactory.java ;
以上是关于Android 启动过程Activity 启动源码分析 ( ActivityThread 流程分析 一 )的主要内容,如果未能解决你的问题,请参考以下文章
Android 启动过程Activity 启动源码分析 ( ActivityThread -> Activity主线程阶段 一 )
Android 启动过程Activity 启动源码分析 ( AMS -> ActivityThreadAMS 线程阶段 二 )
Android 启动过程Activity 启动源码分析 ( AMS -> ActivityThreadAMS 线程阶段 )
Android 启动过程Activity 启动源码分析 ( ActivityThread -> Activity主线程阶段 二 )