Android 是怎么启动一个Acitivity的?

可以把启动过程分为client端和server端。

一、client端在启动一个Activity时进行的工作

备注:我个人理解,client端指的是相对后台ActivityManagerService
进程来说的前台用户可见的进程,如在界面启动某一个Activity的就是Laucher进程。这里则以从home桌面启动一个Activity来分析启动过程:

(1)Launcher
这个进程的主线程,在捕获onClick点击事件后,调用
startActivitySafely
方法,
startActivitySafely
方法内部调用了

startActivity
方法,然后,startActivity方法进而调用Launcher的父类Activity的
startActivity方法;

(2)Activity.startActivity方法
调用startActivityForResult
方法,传入该方法
的requestCode
参数为 -1
,表示 Activity启动成功后,不需要执行 Lanucher.onActivityResult方法处理返回结果;startActivityForResult方法内部需要调用
Instrumentation 的 execStartActivity方法。Instrumentation
对象是用于监控应用程序和系统(主要是 Activity Manager
)的交互过程。

(3)execStartActivity方法会把将要启动的Activity相关信息传送到ActivityManagerService
如果 ActivityMonitor
对启动Activity
进行检查没问题,那么会调用 ActivityManagerNative.getDault
得到ActivityManagerProxy代理对象,然后调用该代理对象的startActivity方法。;

(4)调用ActivityManagerProxy代理对象的startActivity方法实际上是调用
BinderProxy.transact向 Binder驱动发送 START_ACTIVITY_TRANSACTION命令,此时就从Lanucher进程切换到ActivityManagerService进程了。

总结上述四步:源Activity(这里是Launcher)所属进程通过一系列方法,(无论是通过Launcher来启动Activity,还是通过Activity内部调用startActivity接口来启动新的Activit,都通过Binder进程间通信进入到ActivityManagerService进程中,并且调用ActivityManagerService.startActivity接口; 

二、Lanucher进程处理Activity的启动请求,就是Client端的工作,传递给
Server
端的 ActivityManagerService
后。就是ActivityManagerService
进程的处理过程
了。

处理过程将分为 7个阶段

1、第一阶段——预启动检查

这个阶段,主要工作是检查是否有权限启动该Activity,查询系统中是否存在指定Intent的Activity,
检查Intent是否正确,检查当前能否切换Activity,各种检查通过后创建目标Activity的ActivityRecord,
判断是否有可复用的Task
或者Activity
,有则关联ActivityRecord,无则新建Task
,更新
ActivityManagerService中Task的数量,检查回退栈顶是否有显示的Activity,有则暂停。

2、第二阶段——暂停

这个阶段的主要工作就是暂停启动目标 Activity的源Activity,比如,我是从Actvity
A启动Activity B的,那么在启动B之前需要把A暂停,

针对暂停的Activity的后续处理,要么是执行destroy
操作,要么是存入等待stop列表;

3、第三阶段——创建目标Activity所运行的进程

准备切换动画,查询ActivityManagerService
的mProcessNames变量中是否存在指定的进程信息,有则复用,直接启动Activity,无则通过zygote启动一个新的进程。进程启动超时时间一般是10s。

4、第四阶段——加载应用程序Activity

进程入口是 ActivityThread
的main方法,main方法里的主要工作是设置临时进程名,创建
UI主线程ActivityThread
,并调用其attach方法,最后进入主线程的消息循环。接下来的工作是为低内存设备禁用硬件加速,创建应用程序对应的Application,
并初始化,安装 Content Provider,执行Instrumentation的onCreate方法,执行Application的
onCreate方法。

5、第五阶段——显示Acitivity

在ActivityManagerService
所在进程向应用程序主线程的消息循环发送 LANUCHER_ACTIVITY消息,然后在主线程中回调Activity生命周期的onCreate,
onStart,onResume等方法来显示 Activity,onResume方法执行完毕后,需要先把当前显示Activity所在的Task加入最近Task列表,然后才返回ActivityManagerService作后续处理。(在onResume方法之前,还可能会先回调onNewIntent
和 onActivityResult方法)

6、第六阶段——处理处于空闲状态的Activitiy

包括移除ActivityStack消息循环中的超时MSG,停止待停止列表总得Activity,销毁待销毁的Activity,如果是系统启动阶段,还要发送一个ACTION_BOOT_COMPLETEED广播,回收待回收应用程序进程等。最重要的一个操作就是停止源Activity

备注:此文是读书所得,主要归纳于老罗的《Android 源代码情景分析》和杨云君老师的《Android的设计与实现I》。

时间: 2024-10-12 15:55:31

Android 是怎么启动一个Acitivity的?的相关文章

关于Android Studio中启动模拟器时,报VT-x is disabled in BIOS错误的解决办法

有时候在Android Studio中启动一个模拟器去运行程序的时候,会出现下面的错误提示:"Intel HAXM is required to run this AVD,VT-x is disabled in BIOS". 接下来我来说说解决的办法: 1. 首先在SDK Manager中检查是否安装Download Intel x86 Emulator Accelerator (HAXM installer),如果没有安装,则在SDK Manager中下载安装Download Int

Android学习路线(十二)Activity生命周期——启动一个Activity

先占个位置,过会儿来翻译,:p Unlike other programming paradigms in which apps are launched with a main()method, the Android system initiates code in an Activity instance by invoking specific callback methods that correspond to specific stages of its lifecycle. Th

Android实现开机自启动(二)——启动一个activity

在上一篇的基础上,我们收到了广播,现在我们想做点什么..比如启动一个服务,或者启动一个activity.以activity为例,下面聊一聊具体做法. 在onReceive方法里跳转到activity即可,需要注意的是在startActivity之前要setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 或者addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);两个是一个意思. 下面给代码 1 package com.example.testr

Android启动一个只知道包名的应用

我们知道,要启动一个应用,就需要知道应用启动Activity的名称,可是启动Activity的ACTION参数,这样就可以通过startActivity(Intent)来启动,如: /**被启动的应用的包名为com.xx.xx,应用的入口为com.xx.xx.TestLaunchActivity**/ Intent intent = new Intent(); intent.setComponent(new ComponentName("com.xx.xx","com.xx.

Android 安装和启动另外一个应用

有时候一个应用需要启动另外一个应用来完成操作,比如在某些应用中打开闹钟,相机,日历等等. 启动或安装相应的应用的方法: Step1:判断是否安装目标应用.只要知道目标应用的安装包名就可以通过判断"/data/data/packagename"是否存在来实现. [java] view plaincopy 01./** 02. * 判断是否安装目标应用 03. * @param packageName 目标应用安装后的包名 04. * @return 是否已安装目标应用 05. * @au

Android 通过广播启动另一个应用的Activity

需求:现在有应用A和应用B,我需要在A应用中启动B应用中的某个Activity 实现:A应用中的Activity发送广播,关键代码如下: String broadcastIntent = "com.example.android.notepad.NotesList";//自己自定义       Intent intent = new Intent(broadcastIntent);       this.sendBroadcast(intent); B应用中需要一个BroadcastR

Android官方入门文档[12]启动一个活动

Android官方入门文档[12]启动一个活动 Starting an Activity启动一个活动 This lesson teaches you to1.Understand the Lifecycle Callbacks2.Specify Your App's Launcher Activity3.Create a New Instance4.Destroy the Activity 这节课教你1.了解生命周期回调2.指定您的应用程序的启动活动3.创建一个新实例4.销毁活动 You sho

init进程 && 解析Android启动脚本init.rc && 修改它使不启动android && init.rc中启动一个sh文件

Android启动后,系统执行的第一个进程是一个名称为init 的可执行程序.提供了以下的功能:设备管理.解析启动脚本.执行基本的功能.启动各种服务.代码的路径:system/core/init,编译的结果是一个可执行文件:init.这个init 的可执行文件是系统运行的第一个用户空间的程序,它以守护进程的方式运行.启动脚本则就是下面要讲的Init.rc. ======================================================================

Android手机app启动的时候第一个Activity必须是MainActivity吗

原文:Android手机app启动的时候第一个Activity必须是MainActivity吗 Android手机APP启动的第一个Activity是可以自己设置的,不是必须的MainActivity,可以是任何的Activity. 设置Android手机APP启动的第一个Activity得看Android项目里的mainfest.xml文件: android.name属性值是由包名(com.example.login)+启动的Activity类名(Login)组成的,如果要修改APP启动的第一