ImageVerifierCode 换一换
格式:DOCX , 页数:48 ,大小:226.40KB ,
资源ID:20877175      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/20877175.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(Android窗口管理服务WindowManagerService显示Activity组件的启动窗口Starting Window的过程分析文档格式.docx)为本站会员(b****5)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

Android窗口管理服务WindowManagerService显示Activity组件的启动窗口Starting Window的过程分析文档格式.docx

1、这个过程如图2所示。这个过程可以分为6个步骤,接下来我们就详细分析每一个步骤。 Step 1. ActivityStack.startActivityLockedjava view plain copy 在CODE上查看代码片派生到我的代码片public class ActivityStack . / Set to false to disable the preview that is shown while a new activity / is being started. static final boolean SHOW_APP_STARTING_PREVIEW = true; pr

2、ivate final void startActivityLocked(ActivityRecord r, boolean newTask, boolean doResume) final int NH = mHistory.size(); int addPos = -1; / Place a new activity at top of stack, so it is next to interact / with the user. if (addPos / We want to show the starting preview window if we are / switching

3、 to a new task, or the next activitys process is / not currently running. boolean showStartingIcon = newTask; ProcessRecord proc = r.app; if (proc = null) proc = mService.mProcessNames.get(r.processName, r.info.applicationInfo.uid); if (proc = null | proc.thread = null) showStartingIcon = true; mSer

4、vice.mWindowManager.addAppToken( addPos, r, r.task.taskId, r.info.screenOrientation, r.fullscreen); boolean doShow = true; if (newTask) / Even though this activity is starting fresh, we still need / to reset it to make sure we apply affinities to move any / existing activities from other tasks in to

5、 it. / If the caller has requested that the target task be / reset, then do so. if (r.intent.getFlags() &Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) resetTaskIfNeededLocked(r, r); doShow = topRunningNonDelayedActivityLocked(null) = r; if (SHOW_APP_STARTING_PREVIEW & doShow) / Figure out if we a

6、re transitioning from another activity that is / has the same starting icon as the next one. This allows the / window manager to keep the previous window it had previously / created, if it still had one. ActivityRecord prev = mResumedActivity; if (prev != null) / We dont want to reuse the previous s

7、tarting preview if: / (1) The current activity is in a different task. if (prev.task != r.task) prev = null; / (2) The current activity is already displayed. else if (prev.nowVisible) prev = null; mService.mWindowManager.setAppStartingWindow( r, r.packageName, r.theme, r.nonLocalizedLabel, r.labelRe

8、s, r.icon, prev, showStartingIcon); else / If this is the first activity, dont do any fancy animations, / because there is nothing for it to animate on top of. mService.mWindowManager.addAppToken(addPos, r, r.task.taskId, r.info.screenOrientation, r.fullscreen); if (doResume) resumeTopActivityLocked

9、(null); 这个函数定义在文件frameworks/base/services/Java/com/android/server/am/ActivityStack.java中。 参数r描述的就是正在启动的Activity组件,而参数newTask和doResume描述的是是否要将该Activity组件放在一个新的任务中启动,以及是否要马上将该Activity组件启动起来。 ActivityStack类的成员变量mHistory指向的是一个ArrayList,它描述的便是系统的Activity组件堆栈。ActivityStack类的成员函数startActivityLocked首先找到正在启动

10、的Activity组件r在系统的Activity组件堆栈中的位置addPos,然后再将正在启动的Activity组件r保存在这个位置上。 变量NH记录的是将正在启动的Activity组件r插入到系统的Activity组件堆栈中之前系统中已经启动了的Activity组件的个数。如果变量NH的值大于0,那么就说明系统需要执行一个Activity组件切换操作,即需要在系统当前激活的Activity组件和正在启动的Activity组件r之间执行一个切换操作,使得正在启动的Activity组件r成为系统接下来要激活的Activity组件。在切换的过程,需要显示切换动画,即给系统当前激活的Activity

11、组件显示一个退出动画,而给正在启动的Activity组件r显示一个启动动画,以及需要为正在启动的Activity组件r显示一个启动窗口。另一方面,如果变量NH的值等于0,那么系统就不需要执行Activity组件切换操作,或者为为正在启动的Activity组件r显示一个启动窗口,这时候只需要为正在启动的Activity组件r创建一个窗口令牌即可。 ActivityStack类的成员变量mService指向的是一个ActivityManagerService对象,这个ActivityManagerService对象就是系统的Activity组件管理服务,它的成员变量mWindowManager指向

12、的是一个WindowManagerService对象,这个WindowManagerService对象也就是系统的Window管理服务。通过调用WindowManagerService类的成员函数addAppToken就可以为正在启动的Activity组件r创建一个窗口令牌,这个过程可以参考前面一文。 在变量NH的值大于0的情况下,ActivityStack类的成员函数startActivityLocked首先检查用来运行Activity组件r的进程是否已经启动起来了。如果已经启动起来,那么用来描述这个进程的ProcessRecord对象proc的值就不等于null,并且这个ProcessRe

13、cord对象proc的成员变量thread的值也不等于null。如果用来运行Activity组件r的进程还没有启动起来,或者Activity组件r需要运行在一个新的任务中,那么变量showStartingIcon的值就会等于true,用来描述在系统当前处于激活状态的Activity组件没有启动窗口的情况下,要为Activity组件r创建一个新的启动窗口,否则的话,就会将系统当前处于激活状态的Activity组件的启动窗口复用为Activity组件r的启动窗口。 系统当前处于激活状态的Activity组件是通过ActivityStack类的成员变量mResumedActivity来描述的,它的启

14、动窗口可以复用为Activity组件r的启动窗口还需要满足两个额外的条件: 1. Activity组件mResumedActivity与Activity组件r运行在同一个任务中,即它们的成员变量task指向的是同一个TaskRecord对象; 2. Activity组件mResumedActivity当前是不可见的,即它的成员变量nowVisible的值等于false。 这两个条件意味着Activity组件mResumedActivity与Activity组件r运行在同一个任务中,并且Activity组件mResumedActivity的窗口还没有显示出来就需要切换到Activity组件r去。

15、 ActivityStack类的静态成员变量SHOW_APP_STARTING_PREVIEW是用描述系统是否可以为正在启动的Activity组件显示启动窗口,只有在它的值等于true,以及正在启动的Activity组件的窗口接下来是要显示出来的情况下,即变量doShow的值等于true,ActivityManagerService服务才会请求WindowManagerService服务为正在启动的Activity组件设置启动窗口。 一般来说,一个正在启动的Activity组件的窗口接下来是需要显示的,但是正在启动的Activity组件可能会设置一个标志位,用来通知ActivityManage

16、rService服务在它启动的时候,对它运行在的任务进行重置。一个任务被重置之后,可能会导致其它的Activity组件转移到这个任务中来,并且位于位于这个任务的顶端。在这种情况下,系统接下来要显示的窗口就不是正在启动的Activity组件的窗口的了,而是位于正在启动的Activity组件所运行在的任务的顶端的那个Activity组件的窗口。正在启动的Activity组件所运行在的任务同时也是一个前台任务,即它顶端的Activity组件就是系统Activity组件堆栈顶端的Activity组件。 调用参数r所指向一个ActivityRecord对象的成员变量intent所描述的一个Intent对

17、象的成员函数getFlags就可以获得正在启动的Activity组件的标志值,当这个标志值的FLAG_ACTIVITY_RESET_TASK_IF_NEEDED位等于1的时候,就说明正在启动的Activity组件通知ActivityManagerService服务对它运行在的任务进行重置。重置一个任务是通过调用ActivityStack类的成员函数resetTaskIfNeededLocked来实现的。重置了正在启动的Activity组件所运行在的任务之后,再调用ActivityStack类的成员函数topRunningNonDelayedActivityLocked来检查位于系统Activi

18、ty组件堆栈顶端的Activity组件是否就是正在启动的Activity组件,就可以知道正在启动的Activity组件的窗口接下来是否是需要显示的。如果需要显示的话,那么变量doShow的值就等于true。 ActivityManagerService服务请求WindowManagerService服务为正在启动的Activity组件设置启动窗口是通过调用WindowManagerService类的成员函数setAppStartingWindow来实现的。注意,ActivityManagerService服务在请求WindowManagerService服务为正在启动的Activity组件设置

19、启动窗口之前,同样会调用WindowManagerService类的成员函数addAppToken来创建窗口令牌。 ActivityManagerService服务请求WindowManagerService服务为正在启动的Activity组件设置启动窗口之后,如果参数doResume的值等于true,那么就会调用ActivityStack类的成员函数resumeTopActivityLocked继续执行启动参数r所描述的一个Activity组件的操作,这个过程可以参考前面一文。 接下来,我们就继续分析WindowManagerService类的成员函数setAppStartingWindow

20、的实现,以便可以了解WindowManagerService服务是如何为正在启动的Activity组件设置启动窗口的。 Step 2. WindowManagerService.setAppStartingWindow WindowManagerService类的成员函数setAppStartingWindow定义在文件frameworks/base/services/java/com/android/server/WindowManagerService.java中,它的实现比较长,我们分段来阅读:public class WindowManagerService extends IWind

21、owManager.Stub implements Watchdog.Monitor public void setAppStartingWindow(IBinder token, String pkg, int theme, CharSequence nonLocalizedLabel, int labelRes, int icon, IBinder transferFrom, boolean createIfNeeded) synchronized(mWindowMap) AppWindowToken wtoken = findAppWindowToken(token); / If the

22、 display is frozen, we wont do anything until the / actual window is displayed so there is no reason to put in / the starting window. if (mDisplayFrozen | !mPolicy.isScreenOn() return; if (wtoken.startingData ! 参数token描述的是要设置启动窗口的Activity组件,而参数transferFrom描述的是要将启动窗口转移给Activity组件token的Activity组件。从Ste

23、p 1可以知道,这两个Activity组件是运行在同一个任务中的,并且参数token描述的Activity组件Activity组件是正在启动的Activity组件,而参数transferFrom描述的Activity组件是系统当前激活的Activity组件。 这段代码首先调用WindowManagerService类的成员函数findAppWindowToken来获得与参数token对应的一个类型为AppWindowToken的窗口令牌wtoken。如果这个AppWindowToken对象的成员变量startingData的值不等于null,那么就说明参数token所描述的Activity组件

24、已经设置过启动窗口了,因此,WindowManagerService类的成员函数setAppStartingWindow就不用往下处理了。 这段代码还会检查系统屏幕当前是否处于冻结状态,即WindowManagerService类的成员变量mDisplayFrozen的值是否等于true,或者系统屏幕当前是否处于黑屏状态,即indowManagerService类的成员变量mPolicy所指向的一个PhoneWindowManager对象的成员函数isScreenOn的返回值是否等于false。如果是处于上述两种状态的话,那么WindowManagerService类的成员函数setAppSt

25、artingWindow就不用往下处理的。因为在这两种状态下,为token所描述的Activity组件设置的启动窗口是无法显示的。 我们接着往下阅读代码:if (transferFrom ! AppWindowToken ttoken = findAppWindowToken(transferFrom); if (ttoken ! WindowState startingWindow = ttoken.startingWindow; if (startingWindow ! if (mStartingIconInTransition) / In this case, the starting

26、icon has already / been displayed, so start letting windows get / shown immediately without any more transitions. mSkipAppTransitionAnimation = true; final long origId = Binder.clearCallingIdentity(); / Transfer the starting window over to the new / token. wtoken.startingData = ttoken.startingData; wtoken.startingView = ttoken.startingView; wtoken.startingWindow = startingWindow; ttoken.startingData = null; ttoken.starti

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1