Framework源码分析(三):ActivityThread

2024-06-05 16:18

本文主要是介绍Framework源码分析(三):ActivityThread,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

在ActivityManagerService这一篇博客中,我们已经了解AMS在Android系统中是管理系统中Activity的重要类,他通过Binder进程间通信的方式去调度Activity,从而操作Activity的生命周期。那么在这一篇博客中,我们继续通过认识ActivityThread来进一步了解Activity的创建和启动的原理。

简述App启动流程

APP启动流程

从图中的流程来看,首先用户在Android桌面中发起针对某个应用程序的点击事件之后:
(1)LauncherActivity通过Binder进程间通信的方式将应用的信息通过Intent的方式传递给AMS,由AMS进行调度。
(2)如果系统中不存在该进程时,AMS将会请求Zygote服务去fork一个子进程,成功后返回一个pid给AMS,并由AndroidRuntime机制调起ActivityThread中的main()方法。
(3)紧接着,应用程序的Main Looper被创建,ActivityThread被实例化成为对象并将Application的信息以进程间通信的方式再次回馈给AMS。
(4)AMS接收到客户端发来的请求数据之后,首先将应用程序绑定,并启动应用程序的Activity,开始执行Activity的生命周期。

1. 应用程序的入口

ActivityThread的Main方法是应用程序进程的入口。先贴上代码:

    public static void main(String[] args) {Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ActivityThreadMain");SamplingProfilerIntegration.start();// CloseGuard defaults to true and can be quite spammy.  We// disable it here, but selectively enable it later (via// StrictMode) on debug builds, but using DropBox, not logs.CloseGuard.setEnabled(false);Environment.initForCurrentUser();// Set the reporter for event logging in libcoreEventLogger.setReporter(new EventLoggingReporter());// Make sure TrustedCertificateStore looks in the right place for CA certificatesfinal File configDir = Environment.getUserConfigDirectory(UserHandle.myUserId());TrustedCertificateStore.setDefaultUserDirectory(configDir);Process.setArgV0("<pre-initialized>");Looper.prepareMainLooper();ActivityThread thread = new ActivityThread();thread.attach(false);if (sMainThreadHandler == null) {sMainThreadHandler = thread.getHandler();}if (false) {Looper.myLooper().setMessageLogging(newLogPrinter(Log.DEBUG, "ActivityThread"));}// End of event ActivityThreadMain.Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);Looper.loop();throw new RuntimeException("Main thread loop unexpectedly exited");}

在这里需要解释一下,这部分代码都干了哪些事儿:
(1)初始化应用程序中需要使用到的系统路径

Environment.initForCurrentUser();

(2)设置进程名称

Process.setArgV0("<pre-initialized>");

(3)在这里为应用程序的主线程创建了Looper。

Looper.prepareMainLooper();

thread.getHandler()保存了主线程的Handler

if (sMainThreadHandler == null) {sMainThreadHandler = thread.getHandler(); 
}

通过Looper.loop()的调用进入消息循环

Looper.loop();

(4)实例化ActivityThread对象,并通过attach()方法将APP的信息通过进程间通信的方式传递给AMS进行绑定。在下面我们会详细的讲下attach()方法。

ActivityThread thread = new ActivityThread();
thread.attach(false);

2. ApplicationThread

在attach()方法中,可以找到如下代码:

private void attach(boolean system) {sCurrentActivityThread = this;mSystemThread = system;if (!system) {...// 以上省略RuntimeInit.setApplicationObject(mAppThread.asBinder());final IActivityManager mgr = ActivityManagerNative.getDefault();try {mgr.attachApplication(mAppThread);} catch (RemoteException ex) {throw ex.rethrowFromSystemServer();}...// 以下省略}
}
// 实例化应用程序进程对象
final ApplicationThread mAppThread = new ApplicationThread();

首先,将mAppThread对象转换成为binder对象并将其作为应用程序先report给VM,该应用程序就能够获得VM反馈的一些异常和错误。然后通过获得Client端的代理对象,将mAppThread对象作为参数传递给AMS进行调度处理。

ApplicationThread继承了ApplicationThreadNative类,而ApplicationThreadNative又继承了Binder,那么它就拥有了进程间通信的特质,于此同时它最终又实现了IApplicationThread接口,该接口实现了操作App生命周期的各种方法回调。

    @Overridepublic final void attachApplication(IApplicationThread thread) {synchronized (this) {int callingPid = Binder.getCallingPid();final long origId = Binder.clearCallingIdentity();attachApplicationLocked(thread, callingPid);Binder.restoreCallingIdentity(origId);}}
    private final boolean attachApplicationLocked(IApplicationThread thread,int pid) {// Find the application record that is being attached...  either via// the pid if we are running in multiple processes, or just pull the// next app record if we are emulating process with anonymous threads....// 省略以上部分代码try {ProfilerInfo profilerInfo = profileFile == null ? null: new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);// 通过AMS调用bindApplication()方法将进程绑定thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,app.instrumentationUiAutomationConnection, testMode,mBinderTransactionTrackingEnabled, enableTrackAllocation,isRestrictedBackupMode || !normalMode, app.persistent,new Configuration(mConfiguration), app.compat,getCommonServicesLocked(app.isolated),mCoreSettingsObserver.getCoreSettingsLocked());updateLruProcessLocked(app, false, null);app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();} catch (Exception e) {// todo: Yikes!  What should we do?  For now we will try to// start another process, but that could easily get us in// an infinite loop of restarting processes...Slog.wtf(TAG, "Exception thrown during bind of " + app, e);app.resetPackageList(mProcessStats);app.unlinkDeathRecipient();startProcessLocked(app, "bind fail", processName);return false;}... // 省略以下部分代码return true;}

AMS拿到mAppThread的对象之后,首先调用bindApplication()的方法将应用程序绑定,并通过应用程序发送的Activity生命周期的信号对应实现Activity生命周期的操作。

在这里大家可能会思考一个问题就是:Activity是如何执行自己的生命周期的。这个问题我先给自己埋一个坑,在未来的文章中,我把这个问题作为一个章节继续深入讲解。

这篇关于Framework源码分析(三):ActivityThread的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1033549

相关文章

Mysql的主从同步/复制的原理分析

《Mysql的主从同步/复制的原理分析》:本文主要介绍Mysql的主从同步/复制的原理分析,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录为什么要主从同步?mysql主从同步架构有哪些?Mysql主从复制的原理/整体流程级联复制架构为什么好?Mysql主从复制注意

java -jar命令运行 jar包时运行外部依赖jar包的场景分析

《java-jar命令运行jar包时运行外部依赖jar包的场景分析》:本文主要介绍java-jar命令运行jar包时运行外部依赖jar包的场景分析,本文给大家介绍的非常详细,对大家的学习或工作... 目录Java -jar命令运行 jar包时如何运行外部依赖jar包场景:解决:方法一、启动参数添加: -Xb

Apache 高级配置实战之从连接保持到日志分析的完整指南

《Apache高级配置实战之从连接保持到日志分析的完整指南》本文带你从连接保持优化开始,一路走到访问控制和日志管理,最后用AWStats来分析网站数据,对Apache配置日志分析相关知识感兴趣的朋友... 目录Apache 高级配置实战:从连接保持到日志分析的完整指南前言 一、Apache 连接保持 - 性

Linux中的more 和 less区别对比分析

《Linux中的more和less区别对比分析》在Linux/Unix系统中,more和less都是用于分页查看文本文件的命令,但less是more的增强版,功能更强大,:本文主要介绍Linu... 目录1. 基础功能对比2. 常用操作对比less 的操作3. 实际使用示例4. 为什么推荐 less?5.

spring-gateway filters添加自定义过滤器实现流程分析(可插拔)

《spring-gatewayfilters添加自定义过滤器实现流程分析(可插拔)》:本文主要介绍spring-gatewayfilters添加自定义过滤器实现流程分析(可插拔),本文通过实例图... 目录需求背景需求拆解设计流程及作用域逻辑处理代码逻辑需求背景公司要求,通过公司网络代理访问的请求需要做请

Java集成Onlyoffice的示例代码及场景分析

《Java集成Onlyoffice的示例代码及场景分析》:本文主要介绍Java集成Onlyoffice的示例代码及场景分析,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要... 需求场景:实现文档的在线编辑,团队协作总结:两个接口 + 前端页面 + 配置项接口1:一个接口,将o

IDEA下"File is read-only"可能原因分析及"找不到或无法加载主类"的问题

《IDEA下Fileisread-only可能原因分析及找不到或无法加载主类的问题》:本文主要介绍IDEA下Fileisread-only可能原因分析及找不到或无法加载主类的问题,具有很好的参... 目录1.File is read-only”可能原因2.“找不到或无法加载主类”问题的解决总结1.File

8种快速易用的Python Matplotlib数据可视化方法汇总(附源码)

《8种快速易用的PythonMatplotlib数据可视化方法汇总(附源码)》你是否曾经面对一堆复杂的数据,却不知道如何让它们变得直观易懂?别慌,Python的Matplotlib库是你数据可视化的... 目录引言1. 折线图(Line Plot)——趋势分析2. 柱状图(Bar Chart)——对比分析3

Dubbo之SPI机制的实现原理和优势分析

《Dubbo之SPI机制的实现原理和优势分析》:本文主要介绍Dubbo之SPI机制的实现原理和优势,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录Dubbo中SPI机制的实现原理和优势JDK 中的 SPI 机制解析Dubbo 中的 SPI 机制解析总结Dubbo中

C#继承之里氏替换原则分析

《C#继承之里氏替换原则分析》:本文主要介绍C#继承之里氏替换原则,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录C#里氏替换原则一.概念二.语法表现三.类型检查与转换总结C#里氏替换原则一.概念里氏替换原则是面向对象设计的基本原则之一:核心思想:所有引py