【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
消息 ,
;
在 ActivityThread.H
中的 handleMessage
方法中 , 处理
事件的分支中, 调用了 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 okio使用方法,Android 开源框架 Okio 原理剖析「建议收藏」
- android autosize原理,Android屏幕适配头条:autosize的原理
- android sdk安装过程,图文详解Android 3.0 SDK安装教程
- android短信验证码方案,Android开发之属于你的短信验证码(一)
- Android resource linking failed_android sdk location should not
- android进程间通信的方式_Android进程注入
- Android传感器_传感器网络的基本功能
- android 系统浏览器 源码-Android 最最最简单的浏览器代码
- Android 用户态启动流程分析
- 【Android 性能优化】布局渲染优化 ( CPU 与 GPU 架构分析 | 安卓布局显示流程 | 视觉与帧率分析 | 渲染超时卡顿分析 | 渲染过程与优化 )
- 【Android 内存优化】垃圾回收算法 ( 分代收集算法 | Serial 收集器 | ParNew 收集器 | Parallel Scavenge 收集器 | CMS 并发标记清除收集器 )
- 【Android Gradle 插件】Android Studio 工程 Gradle 构建流程 ② ( settings.gradle 构建脚本分析 | 根目录下 build.gradle 分析 )
- 【Android 进程保活】应用进程拉活 ( JobScheduler 拉活 | JobScheduler 使用流程 | JobService 服务 | 不同版本兼容 | 源码资源 )
- 【Android Protobuf 序列化】Protobuf 使用 ( Protobuf 使用文档 | 创建 Protobuf 源文件 | Protobuf 语法 )
- 【Android 安装包优化】资源打包配置 ( resources.arsc 资源映射表 | 配置国际化资源 )
- 【Android Gradle】安卓应用构建流程 ( Java 源码编译 和 AIDL 文件编译 )
- 【Android 插件化】Hook 插件化框架 ( 从 Hook 应用角度分析 Activity 启动流程 一 | Activity 进程相关源码 )
- 【Android 插件化】Hook 插件化框架 ( 从 Hook 应用角度分析 Activity 启动流程 二 | AMS 进程相关源码 | 主进程相关源码 )
- 【Android 启动过程】Android 应用启动流程 | Activity 启动流程
- 【Android 逆向】ART 脱壳 ( InMemoryDexClassLoader 脱壳 | InMemoryDexClassLoader 类加载器脱壳点总结 )
- 【ijkplayer】编译 Android 版本的 ijkplayer ⑥ ( 进入 ijkplayer-android/android 目录 | 执行 compile-ijk.sh 脚本完成编译 )
- 【Android RenderScript】RenderScript 简介 ② ( RenderScript 引入 | RenderScript 简介 )
- Android控制文字水平间距android:letterSpacing详解手机开发
- Android动态替换Application实现详解手机开发
- 8月取代apk 官方揭秘Android aab格式有何优势
- 微信 for Android v8.0.7 正式版
- Android实现PHP连接MySQL进行数据交互(android通过php连接mysql)
- android横竖屏限制的配置方法