【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.Stubimplements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {@Overridepublic 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 , 此时又回到 ActivityThreadif (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
消息 , 110110110 ;
在 ActivityThread.H
中的 handleMessage
方法中 , 处理 110110110 事件的分支中, 调用了 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 stateapp.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 流程分析 二 )
文章目录 前言 一.ActivityManagerService.attachApplicationLocked 二.ActivityStackSupervisor.attachApplication ...
- Activity启动过程——10.0源码分析
对于一个activity,注意不是根activity,它的启动流程往往是通过创建intent,通过startActivity()的方式启动的,我们跟踪的就是安卓10.0这部分的启动流程. 在windo ...
- springboot启动过程_spring5/springboot2源码学习 -- spring boot 应用的启动过程
推荐阅读: Spring全家桶笔记:Spring+Spring Boot+Spring Cloud+Spring MVC 疫情期间"闭关修炼",吃透这本Java核心知识,跳槽面试不 ...
- Mybatis源码之核心流程分析
终于谈到了Mybatis最核心的东西了,最核心的就是通过配置XML文件或注解中的SQL,直接调用接口就能执行配置好的SQL语句并封装成对应的返回类型的数据. 先看一下Mybatis使用示例: //创建 ...
- Android 源码 Wi-Fi 连接流程分析
Wi-Fi 连接过程可以从 Settings App 中点击任意 Wi-Fi 条目连接说起.点击条目以后会弹出一个对话框,根据不同的 Wi-Fi 类型需要填入必要的信息,再点击连接按钮,发起连接过程. ...
- libevent源码学习-----事件驱动流程分析
libevent中事件驱动的大体流程如下 /* 创建事件驱动 */ struct event_base* base = event_base_new(); /**创建一个事件*@param base: ...
- Android shortcut的使用及源码分析
Android shortcut的使用及源码分析 最近遇到了一个切换国家码后部分应用的shortcut未更新的问题,就学习了shortcut的相关知识,在这里分享一下我了解的知识,希望能对大家有帮助. ...
- Android 10.0 Activity启动详解(二)
Android 10.0 Activity启动详解(一) 我们在上一篇博客中已经介绍了关于Activity的一些基础概念.这一篇博客我们以Android 10.0的代码来分析Activity的启动流程 ...
- Android Q 10.1 KeyMaster源码分析(二) - 各家方案的实现
写在之前 这两篇文章是我2021年3月初看KeyMaster的笔记,本来打算等分析完KeyMaster和KeyStore以后再一起做成一系列贴出来,后来KeyStore的分析中断了,这一系列的文章就变 ...
最新文章
- 计算机windows8黑屏怎么办,老司机为你解说win8系统电脑黑屏开不了机的处理办法...
- Oracle 中control_file_record_keep_time参数的解释
- C++入门指南及实战 第三步 基本变量
- Python的gevent协程及协程概念
- 猜数字游戏python程序_python经典小程序:猜数字游戏
- leetcode——15.3Sum
- 浅谈Fluent Ribbon 中的SplitButton
- Git---安装步骤
- 批量生成10个虚拟主机配置
- java面试算法总结_java编程面试过程中常见的10大算法概念汇总
- HDU 6043 Balala Power! 思维 + 码力
- C++ ::什么意思
- bt 与 ed2k 区别
- 网络——设备冗余HSRP
- python 爬取12306验证码
- 【CSS】calc 函数(动态计算长度值)
- 怎样给黑白照片上色?2个技能教你如何给黑白照片上色
- pandas 数据结构--DataFrame
- python 多图绘制
- 反掩码、掩码、通配符
热门文章
- 解决Jenkins Email Extension Plugin发送邮件失败
- Java EE WEB工程师培训-JDBC+Servlet+JSP整合开发之06.JDBC PreparedStatement
- Vmware中安装RHEL5
- 《python3网络爬虫开发实战》--基本库的使用
- 对软连接进行cp,rm
- NSIS 打包.net2.0
- 身为java程序员你需要知道的网站(包含书籍,面试题,架构...)
- auto register volatile 比较总结
- 多分辨率图像的快速查询
- Laravel中使用模型对数据进行操作