Activity启动过程详解

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Activity启动过程详解相关的知识,希望对你有一定的参考价值。

注:只是说明启动activity的过程(ActivityThread如何与ActivityManagerService简称AmS进行进程间通信调用全过程),不解析android从zygote(受精卵)到整个系统服务的启动

具体来讲,启动activity的方式有以下几种:

  1. 在应用程序中startActivity()或startActivityForResult()方法启动指定activity
  2. 在HOME(桌面)程序中单击应用图标,启动新的activity
  3. 按"BACK"键结束当前activity,自动启动上一个activity
  4. 长按“Home”键,显示出当前任务列表,从中选择一个启动。

先分析第2种方式

android的HOMe桌面程序(launcher)是android系统启动的第一个应用程序,其他的应用程序安装后,会在launcher上创建一个快捷图标,我们点击桌面上的快捷图标就会启动相应的app

桌面程序Launcher.java(源码基于4.2.2,我没有下载4.2.2,参考网上源码)

在android4.0\\packages\\apps\\Launcher2\\src\\com\\android\\launcher2

当点击一个应用图标时会执行一连串流程

-》Launcher.onClick(View v)单击app图标

-》Launcher.startActivitySafely(v, intent, tag)这里比4.0多的一个参数,可能性能优化吧

-》Launcher.startActivity(v, intent, tag)

-》Activity.startActivity(intent, opts.toBundle())

-》Activity.startActivityForResult(intent, -1, options); 

到这里直接跳转到第一个问题上来了(直接分析第一个就可以解决第二个)分析点击android桌面app图标启动应用程序的过程

 第4种方式---长按“Home”键,显示出当前任务列表,从中选择一个启动

流程:

 public static final int KEYCODE_HOME            = 3;
PhoneWindowManager.interceptKeyBeforeDispatching()处理长按home事件
showRecentAppsDialog();//弹出近期任务的对话框 
RecentApplicationsDialog.onclick.getContext().startActivity(intent);//到这里流程就相同了


这个调用的其实也是第1种的startActivity()。所以1,2,4可以用相同处理流程解析,在后面接绍第1中方式处理流程-----fly

android长按home键源码分析以及模拟长按home事件--弹出近期任务

第3种方式(原理与第1种大致相同)

假设一个app,ActivityA启动ActivityB,然后ActivityB按下"BACK"键其实执行的是activity的finish()方法

简单流程:

ActivityB.finish() 
Activity.finish() 
ActivityManagerNative.getDefault().finishActivity() 
ActivityManagerService.finishActivity() 
ActivityStack.requestFinishActivityLocked() 
ActivityStack.finishActivityLocked() 
ActivityStack.startPausingLocked() 

ActivityB向AmS发送finish()请求

// If the activity is PAUSING, we will complete the finish once
// it is done pausing; else we can just directly finish it here.

上面解释。AmS会先会在ActivityStack.finishActivityLocked()方法中检查我们要finish的activity的状态是否处于pause状态,如果是将直接执行finish操作,否则,必须先执行startPausingLocked()---这里终点是resume恢复上一个ActivityA,将A显示在前台窗口

IApplicationThread.schedulePauseActivity() 
ActivityThread.schedulePauseActivity() 
ActivityThread.sendMessage() 
ActivityThread.H.sendMessage() 
ActivityThread.H.handleMessage() 
ActivityThread.handlePauseActivity() 
ActivityThread.performPauseActivity() 
Instrumentation.callActivityOnPause() 
Activity.performPause() 
Activity.onPause() 
ActivityManagerNative.getDefault().activityPaused() 
ActivityManagerService.activityPaused() 
ActivityStack.activityPausedLocked() 
ActivityStack.completePauseLocked() 

接上面,AmS通知当前ActivityB进入Paused状态,当ActivityB进入paused状态后即Activity.onPause()方法执行完后,通知AmS我已经执行完pause操作。于是AmS就准备要在ActivityB所在的进程和任务中恢复ActivityA了;

ActivityStack.resumeTopActivityLocked() 
ActivityStack.resumeTopInnerLocked() 
IApplicationThread.scheduleResumeActivity() 
ActivityThread.scheduleResumeActivity() 
ActivityThread.sendMessage() 
ActivityTherad.H.sendMessage() 
ActivityThread.H.handleMessage() 
ActivityThread.H.handleResumeActivity() 
Activity.performResume() 
Activity.performRestart() 
Instrumentation.callActivityOnRestart() 
Activity.onRestart() 
Activity.performStart() 
Instrumentation.callActivityOnStart() 
Activity.onStart() 
Instrumentation.callActivityOnResume() 
Activity.onResume() 

到这里activityA已经启动起来了,但是ActivityB还没有被finish掉,在ActivityThread.H.handleResumeActivity中会

调用Looper.myQueue().addIdleHandler(new Idler()) 这个方法实现ActivityB的最终销毁操作

Looper.myQueue().addIdleHandler(new Idler()) 
ActivityManagerNative.getDefault().activityIdle() 
ActivityManagerService.activityIdle() 
ActivityStackSupervisor.activityIdleInternalLocked() 
ActivityStack.destroyActivityLocked() 
IApplicationThread.scheduleDestoryActivity() 
ActivityThread.scheduleDestoryActivity() 
ActivityThread.sendMessage() 
ActivityThread.H.sendMessage() 
ActivityThread.H.handleMessage() 
ActivityThread.handleDestoryActivity() 
ActivityThread.performDestoryActivity() 
Activity.performStop() 
Instrumentation.callActivityOnStop() 
Activity.onStop() 
Instrumentation.callActivityOnDestory() 
Activity.performDestory() 
Acitivity.onDestory() 
ActivityManagerNative.getDefault().activityDestoryed() 
ActivityManagerService.activityDestoryed() 
ActivityStack.activityDestoryedLocked() 

这就是finish()的全部流程了(具体与WindowsManagerService的交互以后再补充)

具体细节请fly------ Android源码解析之(十五)-->Activity销毁流程

 

第1种方式--ActivityA启动ActivityB为例

从startActivity()开始分析。

简单流程(有时间完整过一遍源码)

 1 Activity.startActivity
 2 Activity.startActivityForResult
 3 Instrumentation.execStartActivity
 4 ActivityManagerProxy.startActivity
 5 ActivityManagerService.startActivity
 6 ActivityStack.startActivityMayWait
 7 ActivityStack.startActivityLocked
 8 ActivityStack.startActivityUncheckedLocked
 9 ActivityStack.resumeTopActivityLocked
10 ActivityStack.startPausingLocked
11 ApplicationThreadProxy.schedulePauseActivity
12 ApplicationThread.schedulePauseActivity
13 ActivityThread.queueOrSendMessage
14 H.handleMessage
15 ActivityThread.handlePauseActivity
16 ActivityManagerProxy.activityPaused
17 ActivityManagerService.activityPaused
18 ActivityStack.activityPaused
19 ActivityStack.completePauseLocked
20 ActivityStack.resumeTopActivityLokced
21 ActivityStack.startSpecificActivityLocked
22 ActivityStack.realStartActivityLocked
23 ApplicationThreadProxy.scheduleLaunchActivity
24 ApplicationThread.scheduleLaunchActivity
25 ActivityThread.queueOrSendMessage
26 H.handleMessage
27 ActivityThread.handleLaunchActivity
28 ActivityThread.performLaunchActivity
29 AcitiviyB.onCreate

Android应用程序内部启动Activity过程(startActivity)的源代码分析

要查看ActivityManagerNative.java,ActivityManagerProxy.java,ActivityManagerService,还有binder关系看一张图就可以了

技术分享

从图中可以看出代理类:使用ActivityManagerProxy代理类,来代理ActivityManagerNative类的子类ActivityManagerService;

所以执行请求都是传递到ActivityManagerService进行处理

Android学习——ActivityManager与Proxy模式的运用







以上是关于Activity启动过程详解的主要内容,如果未能解决你的问题,请参考以下文章

在片段中启动 Activity [重复]

Activity生命周期详解

framework之Activity启动流程(基于Android11源码)

framework之Activity启动流程(基于Android11源码)

framework之Activity启动流程(基于Android11源码)

Google 官方详解 Activity项目实例不容错过!