Android窗口管理服务WindowManagerService对窗口的组织方式分析Word文档格式.docx
- 文档编号:4463059
- 上传时间:2023-05-03
- 格式:DOCX
- 页数:63
- 大小:407.21KB
Android窗口管理服务WindowManagerService对窗口的组织方式分析Word文档格式.docx
《Android窗口管理服务WindowManagerService对窗口的组织方式分析Word文档格式.docx》由会员分享,可在线阅读,更多相关《Android窗口管理服务WindowManagerService对窗口的组织方式分析Word文档格式.docx(63页珍藏版)》请在冰点文库上搜索。
2.ActivityRecord-K对应于AppWindowToken-K,后者描述的一组窗口是{WindowState-C,WindowState-C-1,WindowState-D,WindowState-D-1},其中,WindowState-C-1是WindowState-C的子窗口,WindowState-D-1是WindowState-D的子窗口。
3.ActivityRecord-N对应于AppWindowToken-N,后者描述的一组窗口是{WindowState-E},其中,WindowState-E是系统当前激活的Activity窗口。
4.BinderforIM对应于WindowToken-I,后者描述的一组窗口是{WindowState-I},其中,WindowState-I是WindowState-E的输入法窗口。
5.BinderforWP对应于WindowToken-W,后者描述的一组窗口是{WindowState-W},其中,WindowState-W是WindowState-E的壁纸窗口。
从图1还可以知道,WindowStack中的WindowState是按照它们所描述的窗口的Z轴位置从低到高排列的。
以上就是WindowManagerService服务组织系统中的窗口的抽象模型,接下来我们将分析AppWindowToken、WindowToken和WindowState的一些增加、移动和删除等操作,以便可以对这个抽象模型有一个更深刻的认识。
1.增加AppWindowToken
从前面一文可以知道,一个Activity组件在启动的过程中,ActivityManagerService服务会调用调用WindowManagerService类的成员函数addAppToken来为它增加一个AppWindowToken,如下所示:
[java]viewplaincopy在CODE上查看代码片派生到我的代码片
publicclassWindowManagerServiceextendsIWindowManager.Stub
implementsWatchdog.Monitor{
......
/**
*MappingfromatokenIBindertoaWindowTokenobject.
*/
finalHashMap<
IBinder,WindowToken>
mTokenMap=
newHashMap<
();
*ThesametokensasmTokenMap,storedinalistforefficientiteration
*overthem.
finalArrayList<
WindowToken>
mTokenList=newArrayList<
*Z-ordered(bottom-mostfirst)listofallapplicationtokens,for
*controllingtheorderingofwindowsindifferentapplications.This
*containsWindowTokenobjects.
AppWindowToken>
mAppTokens=newArrayList<
publicvoidaddAppToken(intaddPos,IApplicationTokentoken,
intgroupId,intrequestedOrientation,booleanfullscreen){
synchronized(mWindowMap){
AppWindowTokenwtoken=findAppWindowToken(token.asBinder());
if(wtoken!
=null){
return;
}
wtoken=newAppWindowToken(token);
mAppTokens.add(addPos,wtoken);
mTokenMap.put(token.asBinder(),wtoken);
mTokenList.add(wtoken);
}
这个函数定义在文件frameworks/base/services/java/com/android/server/WindowManagerService.java中。
WindowManagerService类有三个成员变量mTokenMap、mTokenList和mAppTokens,它们都是用来描述系统中的窗口的。
成员变量mTokenMap指向的是一个HashMap,它里面保存的是一系列的WindowToken对象,每一个WindowToken对象都是用来描述一个窗口的,并且是以描述这些窗口的一个Binder对象的IBinder接口为键值的。
例如,对于Activity组件类型的窗口来说,它们分别是以用来描述它们的一个ActivityRecord对象的IBinder接口保存在成员变量mTokenMap所指向的一个HashMap中的。
成员变量mTokenList指向的是一个ArrayList,它里面保存的也是一系列WindowToken对象,这些WindowToken对象与保存在成员变量mTokenMap所指向的一个HashMap中的WindowToken对象是一样的。
成员变量mTokenMap和成员变量mTokenList的区别就在于,前者在给定一个IBinder接口的情况下,可以迅速指出是否存在一个对应的WindowToken对象,而后者可以迅速遍历WindowManagerService服务中的WindowToken对象。
成员变量mAppTokens指向的也是一个ArrayList,不过它里面保存的是一系列AppWindowToken对象,每一个AppWindowToken对象都是用来描述一个Activity组件窗口的,而这些AppWindowToken对象是以它们描述的窗口的Z轴坐标由小到大保存在这个ArrayList中的,这样我们就可以通过这个ArrayList来从上到下或者从下到上地遍历系统中的所有Activity组件窗口。
由于这些AppWindowToken对象所描述的Activity组件窗口也是一个窗口,并且AppWindowToken类是从WindowToken继承下来的,因此,这些AppWindowToken对象还会同时被保存在成员变量mTokenMap所指向的一个HashMap和成员变量mTokenList所指向的一个ArrayList中。
理解了WindowManagerService类的这三个成员变量的含义之后,它的成员函数addAppToken的实现就好理解了,其中,参数token指向的便是用来描述正在启动的Activity组件所对应的一个ActivityRecord对象,而参数addPos用来描述该Activity组件在堆栈中的位置,这个位置同时也是接下来要创建的AppWindowToken对象在WindowManagerService类的mTokenList所描述的一个ArrayList中的位置。
WindowManagerService类的成员函数addAppToken首先调用另外一个成员函数findAppWindowToken来在成员变量mTokenMap所描述的一个HashMap检查是否已经存在一个AppWindowToken。
如果已经存在的话,那么WindowManagerService类的成员函数addAppToken就什么也不做就返回了,否则的话,就会使用参数token来创建一个AppWindowToken对象,并且会将该AppWindowToken对象分别保存在WindowManagerService类的成员变量mTokenMap、mTokenList和mAppTokens中。
2.删除AppWindowToken
删除AppWindowToken是通过调用WindowManagerService类的成员函数removeAppTokensLocked来实现的,如下所示:
privatevoidremoveAppTokensLocked(List<
IBinder>
tokens){
//XXXThisshouldbedonemoreefficiently!
//(takeadvantageofthefactthatbothlistsshouldbe
//orderedinthesameway.)
intN=tokens.size();
for(inti=0;
i<
N;
i++){
IBindertoken=tokens.get(i);
finalAppWindowTokenwtoken=findAppWindowToken(token);
if(!
mAppTokens.remove(wtoken)){
i--;
N--;
WindowManagerService类的成员函数removeAppTokensLocked可以同时删除一组AppWindowToken对象。
参数tokens所描述的是一个IBinder接口列表,与这些IBinder接口所对应的AppWindowToken对象就是接下来要删除的。
WindowManagerService类的成员函数removeAppTokensLocked通过一个for循环来依次调用另外一个成员函数findAppWindowToken,以便可以找到保存在列表tokens中的每一个IBinder接口所对应的AppWindowToken对象,然后将该AppWindowToken对象从WindowManagerService类的成员变量mAppTokens所描述的一个ArrayList中删除。
注意,WindowManagerService类的成员函数removeAppTokensLocked是在内部使用的,它只是把一个AppWindowToken对象从成员变量mAppTokens中删除,而没有从另外两个成员变量mTokenMap和mTokenList中删除。
3.移动AppWindowToken至指定位置
移动AppWindowToken至指定位置是通过调用WindowManagerService类的成员函数moveAppToken来实现的,如下所示:
publicvoidmoveAppToken(intindex,IBindertoken){
checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
"
moveAppToken()"
)){
thrownewSecurityException("
RequiresMANAGE_APP_TOKENSpermission"
);
if(wtoken==null||!
mAppTokens.add(index,wtoken);
finallongorigId=Binder.clearCallingIdentity();
if(tmpRemoveAppWindowsLocked(wtoken)){
reAddAppWindowsLocked(findWindowOffsetLocked(index),wtoken);
updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES);
mLayoutNeeded=true;
performLayoutAndPlaceSurfacesLocked();
Binder.restoreCallingIdentity(origId);
参数token描述的是要移动的AppWindowToken对象所对应的一个IBinder接口,而参数index描述的是该AppWindowToken对象要移动到的位置。
注意,移动一个AppWindowToken对象到指定的位置是需要android.Manifest.permission.MANAGE_APP_TOKENS权限的。
WindowManagerService类的成员函数moveAppToken首先找到与参数token所对应的AppWindowToken对象,并且将该AppWindowToken对象从WindowManagerService类的成员变量mAppTokens所描述的一个ArrayList中移除,这样做的目的是为了接下来可以将该AppWindowToken对象移动至该ArrayList中的指定位置上,即参数index所描述的位置上。
注意,上述操作只是将参数token所对应的AppWindowToken对象移动到了WindowManagerService类的成员变量mAppTokens所描述的一个ArrayList的指定位置上,接下来还需要同时将与该AppWindowToken对象所对应的WindowState对象移动至WindowManagerService服务内部的一个WindowState堆栈合适位置上去。
移动对应的WindowState对象的操作同样也是分两步执行的:
第一步先调用WindowManagerService类的成员函数tmpRemoveAppWindowsLocked来将这些WindowState对象从原来的WindowState堆栈位置移除;
第二步再调用WindowManagerService类的成员函数reAddAppWindowsLocked来将这些WindowState对象插入到WindowState堆栈的合适位置去。
对应的WindowState对象被移动到的合适位置是通过调用WindowManagerService类的成员函数findWindowOffsetLocked来获得的,它的实现如下所示:
*Z-ordered(bottom-mostfirst)listofallWindowobjects.
WindowState>
mWindows=newArrayList<
privateintfindWindowOffsetLocked(inttokenPos){
finalintNW=mWindows.size();
if(tokenPos>
=mAppTokens.size()){
inti=NW;
while(i>
0){
WindowStatewin=mWindows.get(i);
if(win.getAppToken()!
returni+1;
while(tokenPos>
//Findthefirstapptokenbelowthenewpositionthathas
//awindowdisplayed.
finalAppWindowTokenwtoken=mAppTokens.get(tokenPos-1);
if(wtoken.sendingToBottom){
tokenPos--;
continue;
inti=wtoken.windows.size();
WindowStatewin=wtoken.windows.get(i);
intj=win.mChildWindows.size();
while(j>
j--;
WindowStatecwin=win.mChildWindows.get(j);
if(cwin.mSubLayer>
=0){
for(intpos=NW-1;
pos>
=0;
pos--){
if(mWindows.get(pos)==cwin){
returnpos+1;
if(mWindows.get(pos)==win){
return0;
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Android 窗口 管理 服务 WindowManagerService 组织 方式 分析
![提示](https://static.bingdoc.com/images/bang_tan.gif)
链接地址:https://www.bingdoc.com/p-4463059.html