【Android framework】am命令启动Activity流程

源码基于Android 4.4。

am start -W -n com.dfp.test/.TEstActivity

-W:等目标Activity启动后才返回

-n:用于设置Intent的Component

Am.java->run()->runStart()

——intent = makeIntent();

——intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

——mAm.startActivityAndWait();                                        //调用AMS处理startActivityAndWait

ActivityManagerService.java->startActivityAndWait(......)

//一般情况下Activity是由另一个应用发起的,此时IApplicationThread是应用和AMS交互的通道,也可算是调用进程的表示。am不是一个应用进程,所以IApplicationThread caller变量为null。

//requestCode为调用者发送的代码,具体含义由调用者解释。如果该值大于0,AMS会保存该值并通过onActivityResult返回给调用者。用于记录启动了哪个Activity的功能

————mMainStack.startActivityMayWait()                     //4.4中为mStackSupervisor.startActivityMayWait()

//Activity调度需要ActivityStack,是核心角色

//Activity对应管理类为ActivityRecord表示

//Task由一组Activity组成,用于完成一组特定的功能,对应管理类为TaskRecord表示。同一时间只有以个Task可以显示在前台,其余在后台。Task中只有最前端的Activity可以运行,其他会停止运行。以前很多应用,一个Task里的Activity都在同一个Application中,现在很多Task可以由不同Application的Activity组成。

//ActivityStack只保存ActivityStack不保存TaskRecord。直接管理ActivityStack,弱化了Task的概念。提高了效率,降低了结构清晰度。

ActivityStackSupervisor.java->startActivityMayWait()

4.4中新增了mStackSupervisor,部分函数从ActivityStack移到ActivityStackSupervisor,ActivityStack的一些调用会使用mActivityStackSupervisor进行,反之亦是。

对 Task 的操作,AMS 使用 mStackSupervisor 来进行。对于 Acitivity 的操作,AMS 使用 ActivityStack 来进行。

系统中只有两个 ActivityStack,一个是 mHomeStack,用于保存 Launcher 的Activity,另一个是 mFocusedStack,用于保存非 Launcher 的 App 的 Activity。

第一阶段:获取资源和变量

——intnent.getcomponent();                                             //查找Component,如果Component存在,则省去匹配搜索Intent(本例不为null)

——aInfo = resolveActivity();                                             //查询满足条件的ActivityInfo,在resolveActivity内部与uPKMS交互

——callingPid = Binder.getCallingPid();                            //获取调用进程的PID,UID

——callingUid = Binder.getCallingUid();

第二阶段:启动Activity

——int res = startActivityLocked();                                    //启动Activity

————sourceRecord = isInAnyStackLocked();                //发送请求的ActivityRecord

————resultRecord = sourceRecord.resultTo;                //接收启动结果的ActivityRecord。通常是同一个

————callerApp = mService.getRecordForAppLocked(caller);          //如果caller不为空,需要找到对应的ProcessRecord,从而获得PID/VID

————launchFlags = intent.getFlags();                            //获取启动Flags

————mService.checkPermission();                                //检查权限

————mService.checkComponentPermission();

————mService.mController.activityStarting();                //(Monkey测试)交给回调对象处理,由他判断是否能继续后面的行程

————ActivityRecord r = new ActivityRecord();              //创建一个ActivityRecord对象
————mService.checkAppSwitchAllowedLocked(callingPid, callingUid);     //检查调用进程是否有权限切换Application,如果没有则储存起来,有机会再启动它。将保存到mPendingActivityLaunchers中

//没有权限切换意味着当前显示的应用进行了stopAppSwitches。这个方法会使其他Task的Activity无法显示在前端,但同一个Task中的Activity则不受制约。取消禁止切换使用resumeAppSwitches。为了防止使用者不调用resumeAppSwitches,系统设置了一个超时时间(5s),超时则自动resume。在resume中不会处理Pending起来的Activity,但超时会触发处理Pending的Activity。

————mService.doPendingActivityLaunchesLockedd(false);          //启动处于Pending状态的Activity,即之前由于上一步被禁止切换而保存起来的请求。它将先于本次需要启动的Activity处理

————startActivityUncheckedLocked();                          //处理启动请求,为新建的ActivityRecord找到合适的Task

——————//单独分析

——mService.updateConfigureationLocked();                    //如果configuration发生变化,则调用AMS更新configuration

第三阶段:处理结果

——outResult.result = res;                                                 //设置启动结果

——if (res == IActivityManager.START_SUCCESS) mService.wait();            //如果启动成功了,等待启动结果。为什么res返回成功还要等待呢?因为Activity要运行在一个新的应用i进程中,就必须等待那个应用进程正常启动并处理相关请求。注意,只有am设置了-W选项,才会进入wait状态。

——if (err != START_SUCCRSS) sendActivityResultLocked(); return err;     //如果有问题,则返回错误

startActivityUncheckedLocked()

第一阶段

int launchFlags = intent.getFlags();

launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;               //根据sourceRecord.launchMode判断是否需要设置FLAG_ACTIVITY_NEW_TASK。

第二阶段

boolean addingToTask = false;

boolean movedHome = false;

ActivityRecord intentActivity = r.launchMode != ActivityInfo.LAUNCH_SINGLE_INSTANCE ? findTaskLocked(r) : findActivityLocked(intent, r.info);

r.task = intentActivity.task;                                                  //ActivityRecord r

targetStack = intentActivity.task.stack;

//找到合适的Task做一些ActivityStack中的处理

第三阶段

boolean newTask = false;

boolean keepCurTransition = false;

//增加一个Task,如果前面设置了FLAG_ACTIVITY_NEW_TASK

mService.curTask++;                                                           //当前Task数量加一

版权所有,转载请注明出处:

http://www.cnblogs.com/sickworm/p/4220139.html

时间: 2024-12-18 20:30:47

【Android framework】am命令启动Activity流程的相关文章

[Android UI] Service里面启动Activity和Alertdialog

启动Activity源码:(记得要加上Intent.FLAG_ACTIVITY_NEW_TASK) Intent intent = new Intent(); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); intent.setClass(getApplicationContext(),FileBrowserActivity.class); startActivity(intent); 原因:如果一个外部的Activity Context调用sta

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

文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/6703247 上文介绍了Android应用程序的启动过程,即应用程序默认Activity的启动过程,一般来说,这种默认 Activity是在新的进程和任务中启动的:本文将继续分析在应用程序内部启动非默认Activity的过程的源代码,这种非默认Activity一般 是在原来的进程和任务中启动的. 这里,我们像上一篇文章Android应用程序启动过

Android Framework层Power键关机流程(二,关机流程)

二,关机流程 从前一篇博文我们知道,当用户长按Power键时会弹出(关机.重新启动,飞行模式等选项)对话框,我们点击关机,则会弹出关机确认对话框.那么从选项对话框到关机确认对话框又是一个什么流程呢.以下我们在简单分析一下: showGlobalActionsDialog()-->showDialog()-->handleShow()-->createDialog()-->onPress()-->shutdown() PhoneWindowManager.java void s

Android Framework层Power键关机流程(一,Power长按键操作处理)

一:Android处理Power按键长按操作 在Framework层中,Android4.x对Power键(KeyEvent.KEYCODE_POWER)的操作,我们从PhoneWindowManager开始分析,在分析前我这里打印了该方法的堆栈调用信息.大家可以参考一下. public long interceptKeyBeforeDispatching(WindowState win, KeyEvent event, int policyFlags) { ...... android.uti

从零开始学android开发-用Intent启动Activity的方法

启动另外一个Activity,可以有的方法有用setClass()和Component Name 1. 先说在setClass启动一个Activity的方法吧: Intent intent = new Intent(); intent.setClass(this, CreatePlaylist.class) //参数一为当前Package的context,t当前Activity的context就是this,其他Package可能用到createPackageContex()参数二为你要打开的Ac

Android通过包名启动Activity

代码: private void startAppByPkgName(String pkgName){ Intent intent =null; intent = mContext.getPackageManager().getLaunchIntentForPackage(pkgName); if(intent != null){ mContext.startActivity(intent); } }

Android 7.0 ActivityManagerService(2) 启动Activity的过程:一

从这一篇博客开始,我们将阅读AMS启动一个Activity的代码流程. 自己对Activity的启动过程也不是很了解,这里就初步做一个代码阅读笔记,为以后的迭代打下一个基础. 一.基础知识 在分析Activity的启动过程前,有必要先了解一下Activity相关的基础知识. 1.Task和Activity的设计理念 关于Android中Task和Activity的介绍,个人觉得<深入理解Android>中的例子不错. 我们就借鉴其中的例子,进行相应的说明: 上图列出了用户在Android系统上

[Android][Framework]Activity启动流程

开始 从Launcher点击一个App图标,会触发如下动作: LauncherActivity.java protected void (ListView l, View v, int position, long id) { Intent intent = intentForPosition(position); startActivity(intent);} 走到了 Activity.java 的startActivity相关方法: public void startActivity(Int

怎么找Android的启动Activity

怎么找到Android的启动Activity 一.apk反编译,得到程序的源代码.图片.XML配置.语言资源等文件 二.找activity流程: 打开apk反编译后文件的文件夹,找到其中的Androidmanifest.XML文件,用浏览器的方式打开也行! 在浏览器中Ctrl+F搜索文字MAIN,找到MAIN上级activity层的android:name字段,android:name字段后面的值就是用来启动app的activity,appium要用的activity. (号外)最后奉上我反编译