通过实例解析android Activity启动过程

 更新时间:2020年09月28日 14:41:12   作者:海绵般汲取  
这篇文章主要介绍了通过实例解析android Activity启动过程,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

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

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

  • 在应用程序中startActivity()或startActivityForResult()方法启动指定activity
  • 在HOME(桌面)程序中单击应用图标,启动新的activity
  • 按"BACK"键结束当前activity,自动启动上一个activity
  • 长按“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);

到这里直接跳转到第一个问题上来了(直接分析第一个就可以解决第二个)

第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

第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的交互以后再补充)

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

从startActivity()开始分析。

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

Activity.startActivity
Activity.startActivityForResult
Instrumentation.execStartActivity
ActivityManagerProxy.startActivity
ActivityManagerService.startActivity
ActivityStack.startActivityMayWait
ActivityStack.startActivityLocked
ActivityStack.startActivityUncheckedLocked
ActivityStack.resumeTopActivityLocked
ActivityStack.startPausingLocked
ApplicationThreadProxy.schedulePauseActivity
ApplicationThread.schedulePauseActivity
ActivityThread.queueOrSendMessage
H.handleMessage
ActivityThread.handlePauseActivity
ActivityManagerProxy.activityPaused
ActivityManagerService.activityPaused
ActivityStack.activityPaused
ActivityStack.completePauseLocked
ActivityStack.resumeTopActivityLokced
ActivityStack.startSpecificActivityLocked
ActivityStack.realStartActivityLocked
ApplicationThreadProxy.scheduleLaunchActivity
ApplicationThread.scheduleLaunchActivity
ActivityThread.queueOrSendMessage
H.handleMessage
ActivityThread.handleLaunchActivity
ActivityThread.performLaunchActivity
AcitiviyB.onCreate

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

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

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

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

相关文章

  • Android中TextView动态设置缩进距离的方法

    Android中TextView动态设置缩进距离的方法

    项目需求如果在项目中第一行文字需要添加布局的情况我们应该怎么做呢,经过一番考虑和查找我最终选择了缩进的方式解决这个问题,这篇文章主要给大家介绍了关于Android中TextView动态设置缩进距离的相关资料,需要的朋友可以参考下
    2022-04-04
  • Kotlin 作用域函数apply、let、run、with、also使用指南

    Kotlin 作用域函数apply、let、run、with、also使用指南

    在 Kotlin 开发中,作用域函数(Scope Functions)是一组能让代码更简洁、更函数式的高阶函数,本文将结合核心特性、代码示例和对比表格,助你精准掌握apply、let、run、with、also的使用精髓,感兴趣的朋友一起看看吧
    2025-04-04
  • 在android开发中进行数据存储与访问的多种方式介绍

    在android开发中进行数据存储与访问的多种方式介绍

    很多时候我们的软件需要对处理后的数据进行存储或再次访问,Android为数据存储提供了多种方式,首先给大家介绍使用文件如何对数据进行存储,感兴趣的朋友可以了解下哈
    2013-06-06
  • Android Studio实现音乐播放器的全过程(简单易上手)

    Android Studio实现音乐播放器的全过程(简单易上手)

    这篇文章主要给大家介绍了关于Android Studio实现音乐播放器的相关资料,文中通过实例代码以及图文介绍的非常详细,对各位Android开发者们具有一定的参考学习价值,需要的朋友可以参考下
    2022-02-02
  • Android快速分析apk工具aapt的使用教程

    Android快速分析apk工具aapt的使用教程

    这篇文章主要介绍了Android快速分析apk工具aapt的使用教程,本文讲解了什么是aapt、主要用法、使用aapt、查看apk的基本信息、查看基本信息、查看应用权限等内容,需要的朋友可以参考下
    2015-04-04
  • Android实现多级树形选择列表

    Android实现多级树形选择列表

    这篇文章主要为大家详细介绍了Android实现多级树形选择列表,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-04-04
  • listview与SQLite结合实现记事本功能

    listview与SQLite结合实现记事本功能

    这篇文章主要为大家详细介绍了listview与SQLite结合实现记事本功能,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-12-12
  • Android 中clipToPadding 和 clipChildren区别和作用

    Android 中clipToPadding 和 clipChildren区别和作用

    这篇文章主要介绍了Android 中clipToPadding 和 clipChildren区别和作用的相关资料,需要的朋友可以参考下
    2017-06-06
  • Android计时器chronometer使用实例讲解

    Android计时器chronometer使用实例讲解

    这篇文章主要为大家详细介绍了Android计时器chronometer使用实例,介绍了Android计时器chronometer基本使用方法,感兴趣的小伙伴们可以参考一下
    2016-04-04
  • Android使用criteria选择合适的地理位置服务实现方法

    Android使用criteria选择合适的地理位置服务实现方法

    这篇文章主要介绍了Android使用criteria选择合适的地理位置服务实现方法,实例分析了Criteria的具体使用技巧,需要的朋友可以参考下
    2016-01-01

最新评论