日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 人文社科 > 生活经验 >内容正文

生活经验

Android窗口管理服务WindowManagerService计算窗口Z轴位置的过程分析

發(fā)布時(shí)間:2023/11/27 生活经验 46 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Android窗口管理服务WindowManagerService计算窗口Z轴位置的过程分析 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

文章轉(zhuǎn)載至CSDN社區(qū)羅升陽(yáng)的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/8570428

通過(guò)前面幾篇文章的學(xué)習(xí),我們知道了在 Android系統(tǒng)中,無(wú)論是普通的Activity窗口,還是特殊的輸入法窗口和壁紙窗口,它們都是被WindowManagerService服務(wù)組 織在一個(gè)窗口堆棧中的,其中,Z軸位置較大的窗口排列在Z軸位置較小的窗口的上面。有了這個(gè)窗口堆棧之后,WindowManagerService服務(wù) 就可以按照一定的規(guī)則計(jì)算每一個(gè)窗口的Z軸位置了,本文就詳細(xì)分析這個(gè)計(jì)算過(guò)程。

? ? ? ? 基于窗口堆棧來(lái)計(jì)算窗口的Z軸位置是比較有意思的。按照一般的理解,應(yīng)該是先計(jì)算好窗口的Z軸位置,然后再按照Z(yǔ)軸位置的大小來(lái)將各個(gè)窗口排列在堆棧中。 但是,事實(shí)上,窗口是按照其它規(guī)則排列在堆棧中。這些規(guī)則與窗口的類型、創(chuàng)建順序和運(yùn)行狀態(tài)等有關(guān)。例如,狀態(tài)欄窗口總是位于堆棧的頂端,輸入法窗口總是 位于需要輸入法的窗口的上面,而壁紙窗口總是位于需要顯示壁紙的窗口的下面。又如,當(dāng)一個(gè)Activity組件從后臺(tái)激活到前臺(tái)時(shí),與它所對(duì)應(yīng)的窗口就會(huì) 被相應(yīng)地移動(dòng)到窗口堆棧的上面去。

? ? ? ? 從前面Android應(yīng)用程序與SurfaceFlinger服務(wù)的關(guān)系概述和學(xué)習(xí)計(jì)劃和Android系統(tǒng)Surface機(jī)制的SurfaceFlinger服務(wù)簡(jiǎn)要介紹和學(xué)習(xí)計(jì)劃這 兩個(gè)系列的文章可以知道,窗口的UI最終是需要通過(guò)SurfaceFlinger服務(wù)來(lái)統(tǒng)一渲染的,而SurfaceFlinger服務(wù)在渲染窗口的UI 之前,需要計(jì)算基于各個(gè)窗口的Z軸位置來(lái)計(jì)算它們的可見(jiàn)區(qū)域。因此,WindowManagerService服務(wù)計(jì)算好每一個(gè)窗口的Z軸位置之后,還需 要將它們?cè)O(shè)置到SurfaceFlinger服務(wù)中去,以便SurfaceFlinger服務(wù)可以正確地渲染每一個(gè)窗口的UI。

? ? ? ? 上述窗口的Z軸位置計(jì)算和設(shè)置過(guò)程如圖1所示:

圖1 窗口Z軸位置的計(jì)算和設(shè)置過(guò)程

? ? ? ? 接下來(lái),我們就首先分析兩個(gè)需要重新計(jì)算窗口Z軸位置的情景,接著再分析窗口的Z軸位置的計(jì)算過(guò)程,最后分析WindowManagerService服務(wù)將窗口的Z軸設(shè)置到SurfaceFlinger服務(wù)中去的過(guò)程。

? ? ? ? 一.?需要重新計(jì)算窗口Z軸位置的情景

? ? ? ? 這里主要分析兩個(gè)需要重新計(jì)算窗口Z軸位置的情景:應(yīng)用程序增加一個(gè)窗口到WindowManagerService服務(wù)和應(yīng)用程序請(qǐng)求WindowManagerService服務(wù)重新布局一個(gè)窗口。

? ? ? ??從前面Android應(yīng)用程序窗口(Activity)與WindowManagerService服務(wù)的連接過(guò)程分析一文可以知道,應(yīng)用程序請(qǐng)求增加一個(gè)窗口到WindowManagerService服務(wù)的時(shí)候,最終會(huì)調(diào)用到WindowManagerService類的成員函數(shù)addWindow。接下來(lái)我們就主要分析這個(gè)函數(shù)與重新計(jì)算窗口Z軸位置相關(guān)的邏輯,如下所示:

[java] view plaincopy
  1. public?class?WindowManagerService?extends?IWindowManager.Stub????
  2. ????????implements?Watchdog.Monitor?{????
  3. ????......????
  4. ????
  5. ????public?int?addWindow(Session?session,?IWindow?client,????
  6. ????????????WindowManager.LayoutParams?attrs,?int?viewVisibility,????
  7. ????????????Rect?outContentInsets,?InputChannel?outInputChannel)?{????
  8. ????????......????
  9. ????
  10. ????????synchronized(mWindowMap)?{????
  11. ????????????......????
  12. ????
  13. ????????????WindowToken?token?=?mTokenMap.get(attrs.token);?????
  14. ????????????......????
  15. ????
  16. ????????????win?=?new?WindowState(session,?client,?token,????
  17. ????????????????????attachedWindow,?attrs,?viewVisibility);????
  18. ????????????......????
  19. ????
  20. ????????????if?(attrs.type?==?TYPE_INPUT_METHOD)?{????
  21. ????????????????mInputMethodWindow?=?win;??
  22. ????????????????addInputMethodWindowToListLocked(win);??
  23. ????????????????......????
  24. ????????????}?else?if?(attrs.type?==?TYPE_INPUT_METHOD_DIALOG)?{????
  25. ????????????????mInputMethodDialogs.add(win);??
  26. ????????????????addWindowToListInOrderLocked(win,?true);??
  27. ????????????????adjustInputMethodDialogsLocked();??
  28. ????????????????......????
  29. ????????????}?else?{????
  30. ????????????????addWindowToListInOrderLocked(win,?true);????
  31. ????????????????if?(attrs.type?==?TYPE_WALLPAPER)?{????
  32. ????????????????????......????
  33. ????????????????????adjustWallpaperWindowsLocked();????
  34. ????????????????}?else?if?((attrs.flags&FLAG_SHOW_WALLPAPER)?!=?0)?{????
  35. ????????????????????adjustWallpaperWindowsLocked();????
  36. ????????????????}????
  37. ????????????}????
  38. ????????????......????
  39. ????
  40. ????????????assignLayersLocked();????
  41. ????
  42. ????????????......????
  43. ????????}????
  44. ????
  45. ????????......????
  46. ????}????
  47. ????
  48. ????......????
  49. }??????

? ? ? ??這個(gè)函數(shù)定義在文件frameworks/base/services/java/com/android/server/WindowManagerService.java中。

? ? ? ??WindowManagerService類的成員函數(shù)addWindow的具體實(shí)現(xiàn)可以參考Android窗口管理服務(wù)WindowManagerService對(duì)壁紙窗口(Wallpaper Window)的管理分析和Android窗口管理服務(wù)WindowManagerService對(duì)輸入法窗口(Input Method Window)的管理分析這兩篇文章。我們注意到,WindowManagerService類的成員函數(shù)addWindow會(huì)根據(jù)當(dāng)前正在添加的窗口的類型來(lái)調(diào)用不同的成員函數(shù)來(lái)向窗口堆棧的合適位置插入一個(gè)WindowState對(duì)象,即:

? ? ? ? 1. 如果添加的是一個(gè)輸入法窗口,那么就調(diào)用成員函數(shù)addInputMethodWindowToListLocked將它放置在需要顯示輸入法的窗口的上面去;

? ? ? ? 2. 如果添加的是一個(gè)輸入法對(duì)話框,那么就先調(diào)用成員函數(shù)addWindowToListInOrderLocked來(lái)將它插入到窗口堆棧中,接著再調(diào)用成員 函數(shù)adjustInputMethodDialogsLocked來(lái)將它放置在輸入法窗口的上面;

? ? ? ? 3. 如果添加的是一個(gè)普通窗口,那么就直接調(diào)用成員函數(shù)addWindowToListInOrderLocked來(lái)將它插入到窗口堆棧中;

? ? ? ? 4.?如果添加的是一個(gè)普通窗口,并且這個(gè)窗口需要顯示壁紙,那么就先調(diào)用成員函數(shù)addWindowToListInOrderLocked來(lái)將它插入 到窗口堆棧中,接著再調(diào)用成員函數(shù)adjustWallpaperWindowsLocked來(lái)將壁紙窗口放置在它的下面。

? ? ? ? 5.?如果添加的是一個(gè)壁紙窗口,那么就先調(diào)用成員函數(shù)addWindowToListInOrderLocked來(lái)將它插入到窗口堆棧中,接著再調(diào)用成 員函數(shù)adjustWallpaperWindowsLocked來(lái)將它放置在需要顯示壁紙的窗口的下面。

? ? ? ? 無(wú)論如何,WindowManagerService類的成員函數(shù)addWindow最終都會(huì)調(diào)用成員函數(shù)assignLayersLocked來(lái)重新計(jì)算系統(tǒng)中所有窗口的Z軸位置,這是因?yàn)榍懊嫱翱诙褩T黾恿艘粋€(gè)新的窗口。

? ? ? ??從前面Android窗口管理服務(wù)WindowManagerService計(jì)算Activity窗口大小的過(guò)程分析一 文可以知道,應(yīng)用程序進(jìn)程請(qǐng)求WindowManagerService服務(wù)重新布局一個(gè)窗口的時(shí)候,最終會(huì)調(diào)用到 WindowManagerService類的成員函數(shù)relayoutWindow。接下來(lái)我們就主要分析這個(gè)函數(shù)與重新計(jì)算窗口Z軸位置相關(guān)的邏輯, 如下所示:

[java] view plaincopy
  1. public?class?WindowManagerService?extends?IWindowManager.Stub??????????
  2. ????????implements?Watchdog.Monitor?{????????
  3. ????......??????
  4. ??????
  5. ????public?int?relayoutWindow(Session?session,?IWindow?client,??????
  6. ????????????WindowManager.LayoutParams?attrs,?int?requestedWidth,??????
  7. ????????????int?requestedHeight,?int?viewVisibility,?boolean?insetsPending,??????
  8. ????????????Rect?outFrame,?Rect?outContentInsets,?Rect?outVisibleInsets,??????
  9. ????????????Configuration?outConfig,?Surface?outSurface)?{??????
  10. ????????......??????
  11. ??????
  12. ????????synchronized(mWindowMap)?{??????
  13. ????????????WindowState?win?=?windowForClientLocked(session,?client,?false);??????
  14. ????????????......??????
  15. ??????
  16. ????????????int?attrChanges?=?0;??????
  17. ????????????int?flagChanges?=?0;??????
  18. ????????????if?(attrs?!=?null)?{??????
  19. ????????????????flagChanges?=?win.mAttrs.flags?^=?attrs.flags;??????
  20. ????????????????attrChanges?=?win.mAttrs.copyFrom(attrs);??????
  21. ????????????}??????
  22. ????????????......??????
  23. ??????
  24. ????????????boolean?imMayMove?=?(flagChanges&(??????
  25. ????????????????????WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM?|??????
  26. ????????????????????WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE))?!=?0;??????
  27. ??????
  28. ????????????boolean?focusMayChange?=?win.mViewVisibility?!=?viewVisibility??????
  29. ????????????????????||?((flagChanges&WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE)?!=?0)??????
  30. ????????????????????||?(!win.mRelayoutCalled);??????
  31. ??
  32. ????????????boolean?wallpaperMayMove?=?win.mViewVisibility?!=?viewVisibility??
  33. ????????????????????&&?(win.mAttrs.flags?&?FLAG_SHOW_WALLPAPER)?!=?0;??
  34. ????????????......??????
  35. ??????
  36. ??????
  37. ????????????if?(focusMayChange)?{??????
  38. ????????????????......??????
  39. ????????????????if?(updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES))?{??????
  40. ????????????????????imMayMove?=?false;??????
  41. ????????????????}??????
  42. ????????????????......??????
  43. ????????????}??????
  44. ??????
  45. ????????????//?updateFocusedWindowLocked()?already?assigned?layers?so?we?only?need?to??????
  46. ????????????//?reassign?them?at?this?point?if?the?IM?window?state?gets?shuffled??????
  47. ????????????boolean?assignLayers?=?false;??????
  48. ??????
  49. ????????????if?(imMayMove)?{??????
  50. ????????????????if?(moveInputMethodWindowsIfNeededLocked(false)?||?displayed)?{??????
  51. ????????????????????//?Little?hack?here?--?we?-should-?be?able?to?rely?on?the??????
  52. ????????????????????//?function?to?return?true?if?the?IME?has?moved?and?needs??????
  53. ????????????????????//?its?layer?recomputed.??However,?if?the?IME?was?hidden??????
  54. ????????????????????//?and?isn't?actually?moved?in?the?list,?its?layer?may?be??????
  55. ????????????????????//?out?of?data?so?we?make?sure?to?recompute?it.??????
  56. ????????????????????assignLayers?=?true;??????
  57. ????????????????}??????
  58. ????????????}??
  59. ????????????if?(wallpaperMayMove)?{??
  60. ????????????????if?((adjustWallpaperWindowsLocked()&ADJUST_WALLPAPER_LAYERS_CHANGED)?!=?0)?{??
  61. ????????????????????assignLayers?=?true;??
  62. ????????????????}??
  63. ????????????}??????
  64. ????????????......??????
  65. ??????
  66. ????????????if?(assignLayers)?{??????
  67. ????????????????assignLayersLocked();??????
  68. ????????????}??????
  69. ??????
  70. ????????????......??????
  71. ????????}??????
  72. ??????
  73. ????????......??????
  74. ??????
  75. ????????return?(inTouchMode???WindowManagerImpl.RELAYOUT_IN_TOUCH_MODE?:?0)??????
  76. ????????????????|?(displayed???WindowManagerImpl.RELAYOUT_FIRST_TIME?:?0);??????
  77. ????}??????
  78. ??????
  79. ????......??????
  80. }??????

? ? ? ??這個(gè)函數(shù)定義在文件frameworks/base/services/java/com/android/server/WindowManagerService.java中。

? ? ? ??WindowManagerService類的成員函數(shù)relayoutWindow具體實(shí)現(xiàn)可以參考Android窗口管理服務(wù)WindowManagerService對(duì)壁紙窗口(Wallpaper Window)的管理分析和Android窗口管理服務(wù)WindowManagerService對(duì)輸入法窗口(Input Method Window)的管理分析這兩篇文章,與窗口Z軸位置計(jì)算相關(guān)的邏輯大概是這樣的:

? ? ? ? 1. 如果系統(tǒng)當(dāng)前獲得焦點(diǎn)的窗口可能發(fā)生了變化,那么就會(huì)調(diào)用成員函數(shù)updateFocusedWindowLocked來(lái)重新計(jì)算系統(tǒng)當(dāng)前應(yīng)該獲得焦點(diǎn)的 窗口。如果系統(tǒng)當(dāng)前獲得焦點(diǎn)的窗口真的發(fā)生了變化,即窗口堆棧的窗口排列發(fā)生了變化,那么在調(diào)用成員函數(shù) updateFocusedWindowLocked的時(shí)候,就會(huì)調(diào)用成員函數(shù)assignLayersLocked來(lái)重新計(jì)算系統(tǒng)中所有窗口的Z軸位 置。

? ? ? ? 2. 如果系統(tǒng)中的輸入法窗口可能需要移動(dòng),那么就會(huì)調(diào)用成員函數(shù)moveInputMethodWindowsIfNeededLocked來(lái)檢查是否真的需 要移動(dòng)輸入法窗口。如果需要移動(dòng),那么成員函數(shù)moveInputMethodWindowsIfNeededLocked的返回值就會(huì)等于true,這 時(shí)候就說(shuō)明輸入法窗口在窗口堆棧中的位置發(fā)生了變化,因此,就會(huì)將變量assignLayers的值設(shè)置為true,表示接下來(lái)需要重新計(jì)算系統(tǒng)中所有窗 口的Z軸位置。

? ? ? ? 3. 如果當(dāng)前正在請(qǐng)求調(diào)整其布局的窗口是由不可見(jiàn)變化可見(jiàn)的,即變量displayed的值等于true,那么接下來(lái)也是需要重新計(jì)算系統(tǒng)中所有窗口的Z軸位置的,因此,就會(huì)將assignLayers的值設(shè)置為true。

? ? ? ? 4.?如果系統(tǒng)中的壁紙窗口可能需要移動(dòng),那么就會(huì)調(diào)用成員函數(shù)adjustWallpaperWindowsLocked來(lái)檢查是否真的需要移動(dòng)壁紙窗 口。如果需要移動(dòng),那么成員函數(shù)adjustWallpaperWindowsLocked的返回值的 ADJUST_WALLPAPER_LAYERS_CHANGED位就會(huì)等于1,這時(shí)候就說(shuō)明壁紙窗口在窗口堆棧中的位置發(fā)生了變化,因此,就會(huì)將變量 assignLayers的值設(shè)置為true,表示接下來(lái)需要重新計(jì)算系統(tǒng)中所有窗口的Z軸位置。

? ? ? ? 經(jīng)過(guò)上述的一系列操作后,如果得到的變量assignLayers的值設(shè)置等于true,那么WindowManagerService類的成員函數(shù) relayoutWindow就會(huì)調(diào)用成員函數(shù)assignLayersLocked來(lái)重新計(jì)算系統(tǒng)中所有窗口的Z軸位置。

? ? ? ? 二.?計(jì)算系統(tǒng)中所有窗口的Z軸位置

? ? ? ? 從前面第一部分的內(nèi)容可以知道,一旦窗口堆棧中的窗口發(fā)生了變化,那么WindowManagerService類的成員函數(shù)assignLayersLocked就會(huì)調(diào)用來(lái)計(jì)算系統(tǒng)中所有窗口的Z軸位置。

? ? ? ? 窗口的Z軸位置除了與它在窗口堆棧中的位置有關(guān)之外,還與窗口的類型有關(guān)。窗口的類型在創(chuàng)建的時(shí)候就已經(jīng)是確定了 的,WindowManagerService服務(wù)在為它創(chuàng)建一個(gè)WindowState對(duì)象的時(shí)候,就會(huì)根據(jù)它的類型得到一個(gè)BaseLayer值,這 個(gè)BaseLayer值在計(jì)算它的Z軸位置的時(shí)候會(huì)用到。

? ? ? ? 接下來(lái)我們就通過(guò)WindowState類的構(gòu)造函數(shù)來(lái)分析一個(gè)窗口的BaseLayer值是如何確定的,如下所示:

[java] view plaincopy
  1. public?class?WindowManagerService?extends?IWindowManager.Stub??
  2. ????????implements?Watchdog.Monitor?{??
  3. ????......??
  4. ??
  5. ????/**?How?much?to?multiply?the?policy's?type?layer,?to?reserve?room?
  6. ?????*?for?multiple?windows?of?the?same?type?and?Z-ordering?adjustment?
  7. ?????*?with?TYPE_LAYER_OFFSET.?*/??
  8. ????static?final?int?TYPE_LAYER_MULTIPLIER?=?10000;??
  9. ??
  10. ????/**?Offset?from?TYPE_LAYER_MULTIPLIER?for?moving?a?group?of?windows?above?
  11. ?????*?or?below?others?in?the?same?layer.?*/??
  12. ????static?final?int?TYPE_LAYER_OFFSET?=?1000;??
  13. ????......??
  14. ??
  15. ????private?final?class?WindowState?implements?WindowManagerPolicy.WindowState?{??
  16. ????????......??
  17. ??
  18. ????????final?int?mBaseLayer;??
  19. ????????final?int?mSubLayer;??
  20. ????????......??
  21. ??
  22. ????????WindowState(Session?s,?IWindow?c,?WindowToken?token,??
  23. ???????????????WindowState?attachedWindow,?WindowManager.LayoutParams?a,??
  24. ???????????????int?viewVisibility)?{??
  25. ????????????......??
  26. ??
  27. ????????????if?((mAttrs.type?>=?FIRST_SUB_WINDOW?&&??
  28. ????????????????????mAttrs.type?<=?LAST_SUB_WINDOW))?{??
  29. ????????????????//?The?multiplier?here?is?to?reserve?space?for?multiple??
  30. ????????????????//?windows?in?the?same?type?layer.??
  31. ????????????????mBaseLayer?=?mPolicy.windowTypeToLayerLw(??
  32. ????????????????????????attachedWindow.mAttrs.type)?*?TYPE_LAYER_MULTIPLIER??
  33. ????????????????????????+?TYPE_LAYER_OFFSET;??
  34. ????????????????mSubLayer?=?mPolicy.subWindowTypeToLayerLw(a.type);??
  35. ????????????????......??
  36. ????????????}?else?{??
  37. ????????????????//?The?multiplier?here?is?to?reserve?space?for?multiple??
  38. ????????????????//?windows?in?the?same?type?layer.??
  39. ????????????????mBaseLayer?=?mPolicy.windowTypeToLayerLw(a.type)??
  40. ????????????????????????*?TYPE_LAYER_MULTIPLIER??
  41. ????????????????????????+?TYPE_LAYER_OFFSET;??
  42. ????????????????mSubLayer?=?0;??
  43. ????????????????......??
  44. ????????????}??
  45. ??
  46. ????????????......??
  47. ????????}??
  48. ??
  49. ????????......??
  50. ????}??
  51. ??
  52. ????......??
  53. }??

? ? ? ??這個(gè)函數(shù)定義在文件frameworks/base/services/java/com/android/server/WindowManagerService.java中。

? ? ? ??一個(gè)窗口除了有一個(gè)BaseLayer值之外,還有一個(gè)SubLayer值,分別保存在一個(gè)對(duì)應(yīng)的WindowState對(duì)象的成員變量mBaseLayer和mSubLayer。SubLayer值是用來(lái)描述一個(gè)窗口是否是另外一個(gè)窗口的子窗口的。

? ? ? ? 假設(shè)一個(gè)窗口是另外一個(gè)窗口的子窗口,那么參數(shù)attachedWindow所描述的窗口就是父窗口,這時(shí)候子窗口的BaseLayer值就等于父窗口的BaseLayer值,而SubLayer值要么大于0,要么小于0,這與它自己的具體類型有關(guān)。

? ? ? ??假設(shè)一個(gè)窗口不是另外一個(gè)窗口的子窗口,那么這個(gè)窗口的BaseLayer值就與它自己的具體類型有關(guān),而SubLayer值就等于0。

? ? ? ? 現(xiàn)在的關(guān)鍵就是要根據(jù)窗口的類型來(lái)計(jì)算它的BaseLayer值和SubLayer值,它們分別是通過(guò)調(diào)用WindowManagerService類的 成員變量mPolicy所指向的一個(gè)PhoneWindowManager對(duì)象的成員函數(shù)windowTypeToLayerLw和 subWindowTypeToLayerLw來(lái)計(jì)算得到的。這里有兩個(gè)地方是需要注意的。

? ? ? ? 第一個(gè)地方是PhoneWindowManager對(duì)象的成員函數(shù)windowTypeToLayerLw的返回值并且不是一個(gè)窗口的最終的 BaseLayer值,而是要將它的返回值乘以一個(gè)常量TYPE_LAYER_MULTIPLIER,再加上另外一個(gè)常量 TYPE_LAYER_OFFSET之后,才得到最終的BaseLayer值。這是因?yàn)樵贏ndroid系統(tǒng)中,相同類型的窗口的Z軸位置都是有著相同的 值域,而不同類型的窗口的Z軸位置都是處于兩個(gè)不相交的值域。例如,假設(shè)有兩種不同類型的窗口,它們的Z軸位置的值域分別為[a, b]和[c, d],那么[a, b]和[c, d]的交集一定等于空。又由于每一種類型的窗口的數(shù)量是不確定的,因此,WindowManagerService服務(wù)就需要為每一種類型的窗口都預(yù)留一 個(gè)范圍足夠大的值域,以便可以滿足要求。

? ? ? ?WindowManagerService服務(wù)是如何為類型相同的窗口的Z軸位置預(yù)留一個(gè)范圍足夠大的值域的呢?我們假設(shè)類型為t的窗口的Z軸位置的值 域?yàn)閇a, b],并且以t為參數(shù)調(diào)用PhoneWindowManager對(duì)象的成員函數(shù)windowTypeToLayerLw的返回值為T(mén),那么a的值就等于T *?TYPE_LAYER_MULTIPLIER +?TYPE_LAYER_OFFSET,而b的值就等于(T - 1) *?TYPE_LAYER_MULTIPLIER +?TYPE_LAYER_OFFSET - 1,即從T *?TYPE_LAYER_MULTIPLIER +?TYPE_LAYER_OFFSET開(kāi)始,一共預(yù)留了TYPE_LAYER_MULTIPLIER個(gè)值作為類型為t窗口的Z軸位置。由于 TYPE_LAYER_MULTIPLIER的值定義為10000,而TYPE_LAYER_OFFSET的值定義為1000,因此,每一種類型的窗口都 預(yù)留有一個(gè)足夠大的值域來(lái)作為Z軸位置。

? ? ? ?第二個(gè)地方是窗口的SubLayer值并不直接參與窗口的Z軸位置的計(jì)算,但是它會(huì)影響到窗口在窗口堆棧的位置。接下來(lái)我們就會(huì)看到,窗口在窗口堆棧的位置是會(huì)影響到它的Z軸位置的計(jì)算的,因此,窗口的SubLayer間接地參與了窗口的Z軸位置的計(jì)算。

? ? ? ?窗口的SubLayer值是如何影響到窗口在窗口堆棧的位置的呢?在前面Android窗口管理服務(wù)WindowManagerService對(duì)窗口的組織方式分析一 文中,在分析WindowManagerService類的成員函數(shù)addWindowToListInOrderLocked的實(shí)現(xiàn)時(shí)提到,如果一個(gè)窗 口是另外一個(gè)窗口的子窗口,那么當(dāng)它的SubLayer值小于0的時(shí)候,它就會(huì)位于父窗口的下面,否則的話,就會(huì)位于父窗口的上面。

? ? ? ?在繼續(xù)分析WindowManagerService類的成員函數(shù)assignLayersLocked之前,我們首先分析 PhoneWindowManager類的成員函數(shù)windowTypeToLayerLw和subWindowTypeToLayerLw的實(shí)現(xiàn),以便 可以了解一個(gè)窗口的BaseLayer值和SubLayer值是如何確定的。

? ? ? ?PhoneWindowManager類的成員函數(shù)windowTypeToLayerLw的實(shí)現(xiàn)如下所示:

[java] view plaincopy
  1. public?class?PhoneWindowManager?implements?WindowManagerPolicy?{??
  2. ????......??
  3. ??
  4. ????public?int?windowTypeToLayerLw(int?type)?{??
  5. ????????if?(type?>=?FIRST_APPLICATION_WINDOW?&&?type?<=?LAST_APPLICATION_WINDOW)?{??
  6. ????????????return?APPLICATION_LAYER;??
  7. ????????}??
  8. ????????switch?(type)?{??
  9. ????????case?TYPE_STATUS_BAR:??
  10. ????????????return?STATUS_BAR_LAYER;??
  11. ????????case?TYPE_STATUS_BAR_PANEL:??
  12. ????????????return?STATUS_BAR_PANEL_LAYER;??
  13. ????????case?TYPE_SYSTEM_DIALOG:??
  14. ????????????return?SYSTEM_DIALOG_LAYER;??
  15. ????????case?TYPE_SEARCH_BAR:??
  16. ????????????return?SEARCH_BAR_LAYER;??
  17. ????????case?TYPE_PHONE:??
  18. ????????????return?PHONE_LAYER;??
  19. ????????case?TYPE_KEYGUARD:??
  20. ????????????return?KEYGUARD_LAYER;??
  21. ????????case?TYPE_KEYGUARD_DIALOG:??
  22. ????????????return?KEYGUARD_DIALOG_LAYER;??
  23. ????????case?TYPE_SYSTEM_ALERT:??
  24. ????????????return?SYSTEM_ALERT_LAYER;??
  25. ????????case?TYPE_SYSTEM_ERROR:??
  26. ????????????return?SYSTEM_ERROR_LAYER;??
  27. ????????case?TYPE_INPUT_METHOD:??
  28. ????????????return?INPUT_METHOD_LAYER;??
  29. ????????case?TYPE_INPUT_METHOD_DIALOG:??
  30. ????????????return?INPUT_METHOD_DIALOG_LAYER;??
  31. ????????case?TYPE_SYSTEM_OVERLAY:??
  32. ????????????return?SYSTEM_OVERLAY_LAYER;??
  33. ????????case?TYPE_SECURE_SYSTEM_OVERLAY:??
  34. ????????????return?SECURE_SYSTEM_OVERLAY_LAYER;??
  35. ????????case?TYPE_PRIORITY_PHONE:??
  36. ????????????return?PRIORITY_PHONE_LAYER;??
  37. ????????case?TYPE_TOAST:??
  38. ????????????return?TOAST_LAYER;??
  39. ????????case?TYPE_WALLPAPER:??
  40. ????????????return?WALLPAPER_LAYER;??
  41. ????????}??
  42. ????????Log.e(TAG,?"Unknown?window?type:?"?+?type);??
  43. ????????return?APPLICATION_LAYER;??
  44. ????}??
  45. ??
  46. ????......??
  47. }??

? ? ? ?這個(gè)函數(shù)定義在frameworks/base/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java文件中。

? ? ? ?從這里就可以看出,每一種窗口類型type都對(duì)應(yīng)有一個(gè)BaseLayer值,即每一個(gè)TYPE_XXX值都對(duì)應(yīng)有一個(gè)XXX_LAYER值,其 中,TYPE_XXX值定義在WindowManager.LayoutParams類中,而XXX_LAYER值就定義在 PhoneWindowManager類中,它們的對(duì)應(yīng)關(guān)系如圖2所示:

圖2 窗口類型與窗口BaseLayer值的對(duì)應(yīng)關(guān)系

? ? ? ?注意,如果參數(shù)type的值小于FIRST_APPLICATION_WINDOW,或者大于LAST_APPLICATION_WINDOW,或者不 是圖2列出來(lái)的其中一個(gè)值,那么PhoneWindowManager類的成員函數(shù)windowTypeToLayerLw就會(huì)返回一個(gè) APPLICATION_LAYER(2)值給調(diào)用者。

? ? ? ?PhoneWindowManager類的成員函數(shù)subWindowTypeToLayerLw的實(shí)現(xiàn)如下所示:

[java] view plaincopy
  1. public?class?PhoneWindowManager?implements?WindowManagerPolicy?{??
  2. ????......??
  3. ??
  4. ????public?int?subWindowTypeToLayerLw(int?type)?{??
  5. ????????switch?(type)?{??
  6. ????????case?TYPE_APPLICATION_PANEL:??
  7. ????????case?TYPE_APPLICATION_ATTACHED_DIALOG:??
  8. ????????????return?APPLICATION_PANEL_SUBLAYER;??
  9. ????????case?TYPE_APPLICATION_MEDIA:??
  10. ????????????return?APPLICATION_MEDIA_SUBLAYER;??
  11. ????????case?TYPE_APPLICATION_MEDIA_OVERLAY:??
  12. ????????????return?APPLICATION_MEDIA_OVERLAY_SUBLAYER;??
  13. ????????case?TYPE_APPLICATION_SUB_PANEL:??
  14. ????????????return?APPLICATION_SUB_PANEL_SUBLAYER;??
  15. ????????}??
  16. ????????Log.e(TAG,?"Unknown?sub-window?type:?"?+?type);??
  17. ????????return?0;??
  18. ????}??
  19. ??
  20. ????......??
  21. }??

? ? ? ??這個(gè)函數(shù)定義在frameworks/base/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java文件中。

? ? ? ??從這里就可以看出,只有類型為T(mén)YPE_APPLICATION_PANEL、TYPE_APPLICATION_MEDIA、 TYPE_APPLICATION_MEDIA_OVERLAY和TYPE_APPLICATION_SUB_PANEL的窗口才對(duì)應(yīng)有一個(gè) SubLayer值,它們的對(duì)應(yīng)關(guān)系如圖3所示:

圖3 窗口類型與窗口SubLayer值的對(duì)應(yīng)關(guān)系

? ? ? ? 在圖3中,TYPE_XXX值定義在WindowManager.LayoutParams類中,而XXX_LAYER值就定義在 PhoneWindowManager類中。注意,有兩種特殊的多媒體窗口TYPE_APPLICATION_MEDIA和 TYPE_APPLICATION_MEDIA_OVERLAY,它們是用來(lái)顯示多媒體的,例如,用來(lái)顯示視頻,并且它們都是附加在應(yīng)用程序窗口之上的, 但是由于它們的SubLayer值為負(fù)數(shù),因此它們實(shí)際上是位于宿主窗口之下的。類型為T(mén)YPE_APPLICATION_MEDIA的窗口有一個(gè)魔術(shù), 它會(huì)在宿主窗口里面挖一個(gè)洞,以便可以將自己顯示出來(lái),而類型為T(mén)YPE_APPLICATION_MEDIA_OVERLAY背景一般都是透明的,位于 類型為T(mén)YPE_APPLICATION_MEDIA的窗口,可以用來(lái)顯示視頻的字幕之類的東西。實(shí)際上,類型為 TYPE_APPLICATION_MEDIA和TYPE_APPLICATION_MEDIA_OVERLAY的窗口也稱為SurfaceView。 SurfaceView很特殊,它與普通的View的最大區(qū)別就在于它們有獨(dú)立的繪圖表面,于是它們就可以在一個(gè)獨(dú)立的子線程里面進(jìn)行UI渲染。

? ? ? ? 理解了窗口的BaseLayer值和SubLayer值的計(jì)算過(guò)程之外,接下來(lái)我們就可以分析WindowManagerService類的成員函數(shù)assignLayersLocked的實(shí)現(xiàn)了,如下所示:

[java] view plaincopy
  1. public?class?WindowManagerService?extends?IWindowManager.Stub??
  2. ????????implements?Watchdog.Monitor?{??
  3. ????......??
  4. ??
  5. ????/**?How?much?to?increment?the?layer?for?each?window,?to?reserve?room?
  6. ?????*?for?effect?surfaces?between?them.?
  7. ?????*/??
  8. ????static?final?int?WINDOW_LAYER_MULTIPLIER?=?5;??
  9. ????......??
  10. ??
  11. ????private?final?void?assignLayersLocked()?{??
  12. ????????int?N?=?mWindows.size();??
  13. ????????int?curBaseLayer?=?0;??
  14. ????????int?curLayer?=?0;??
  15. ????????int?i;??
  16. ??
  17. ????????for?(i=0;?i<N;?i++)?{??
  18. ????????????WindowState?w?=?mWindows.get(i);??
  19. ????????????if?(w.mBaseLayer?==?curBaseLayer?||?w.mIsImWindow??
  20. ????????????????????||?(i?>?0?&&?w.mIsWallpaper))?{??
  21. ????????????????curLayer?+=?WINDOW_LAYER_MULTIPLIER;??
  22. ????????????????w.mLayer?=?curLayer;??
  23. ????????????}?else?{??
  24. ????????????????curBaseLayer?=?curLayer?=?w.mBaseLayer;??
  25. ????????????????w.mLayer?=?curLayer;??
  26. ????????????}??
  27. ????????????if?(w.mTargetAppToken?!=?null)?{??
  28. ????????????????w.mAnimLayer?=?w.mLayer?+?w.mTargetAppToken.animLayerAdjustment;??
  29. ????????????}?else?if?(w.mAppToken?!=?null)?{??
  30. ????????????????w.mAnimLayer?=?w.mLayer?+?w.mAppToken.animLayerAdjustment;??
  31. ????????????}?else?{??
  32. ????????????????w.mAnimLayer?=?w.mLayer;??
  33. ????????????}??
  34. ????????????if?(w.mIsImWindow)?{??
  35. ????????????????w.mAnimLayer?+=?mInputMethodAnimLayerAdjustment;??
  36. ????????????}?else?if?(w.mIsWallpaper)?{??
  37. ????????????????w.mAnimLayer?+=?mWallpaperAnimLayerAdjustment;??
  38. ????????????}??
  39. ????????????......??
  40. ????????}??
  41. ????}??
  42. ???
  43. ????......??
  44. }??

? ? ? ??這個(gè)函數(shù)定義在文件frameworks/base/services/java/com/android/server/WindowManagerService.java中。

? ? ? ? 注意,在調(diào)用WindowManagerService類的成員函數(shù)assignLayersLocked之前,系統(tǒng)中的所有窗口在窗口堆棧中的位置都是 已經(jīng)排列好了的,這時(shí)候WindowManagerService類的成員函數(shù)assignLayersLocked就從下往上遍歷窗口堆棧,以連排列在 一起的類型相同的窗口為單位來(lái)計(jì)算每一個(gè)窗口的Z位置,即:

? ? ? ? 1. 每次遇到一個(gè)窗口,它的BaseLayer值與上一次計(jì)算的窗口的BaseLayer值不相等,就開(kāi)始一個(gè)新的計(jì)算單元。

? ? ? ? 2. 在每一個(gè)計(jì)算單元中,第一個(gè)窗口的Z軸位置就等于它的BaseLayer值,而之后的每一個(gè)窗口的Z軸位置都比前一個(gè)窗口的Z軸位置大WINDOW_LAYER_MULTIPLIER。

? ? ? ? 這個(gè)窗口的Z軸位置計(jì)算方法有三個(gè)地方是需要注意的。 ? ? ? ?

? ? ? ? 第一個(gè)地方是從第2點(diǎn)可以看出,每一個(gè)窗口的Z軸位置值都不是連續(xù)的,這樣就在每?jī)蓚€(gè)窗口之間都保留了一定的位置來(lái)插入其它窗口。

? ? ? ? 第二個(gè)地方是由于系統(tǒng)中所有類型相同的窗口不一定都是排列在一起的,因此,就有可能出現(xiàn)有些類型相同的窗口具有相同的Z軸位置。 WindowManagerService服務(wù)并不關(guān)心兩個(gè)不同窗口的Z軸位置是否相同,但是SurfaceFlinger服務(wù)就需要關(guān)心了,因?yàn)?SurfaceFlinger服務(wù)需要是按照Z(yǔ)軸從大到小的順序來(lái)計(jì)算窗口的可見(jiàn)性。那么SurfaceFlinger服務(wù)是如何確定兩個(gè)Z軸位置相同的 窗口的次序的呢?從前面Android應(yīng)用程序與SurfaceFlinger服務(wù)的關(guān)系概述和學(xué)習(xí)計(jì)劃和Android系統(tǒng)Surface機(jī)制的SurfaceFlinger服務(wù)簡(jiǎn)要介紹和學(xué)習(xí)計(jì)劃這 兩個(gè)系列的文章可以知道,每一個(gè)窗口在SurfaceFlinger服務(wù)都對(duì)應(yīng)有一個(gè)Layer對(duì)象,而每一個(gè)Layer對(duì)象都有一個(gè)sequence 值,其中,先創(chuàng)建的Layer對(duì)象的sequence值大于后創(chuàng)建的Layer對(duì)象的sequence值。這樣,SurfaceFlinger服務(wù)在計(jì)算 對(duì)于兩個(gè)Z軸位置相同的窗口的可見(jiàn)性的時(shí)候,就會(huì)比較它們所對(duì)應(yīng)的Layer對(duì)象的sequence值,其中,sequence值大的窗口的可見(jiàn)性會(huì)先于 sequence值小的窗口得到計(jì)算,即先計(jì)算后創(chuàng)建的窗口的可見(jiàn)性,再計(jì)算先創(chuàng)建的窗口的可見(jiàn)性。

? ? ? ? 第三個(gè)地方是有兩種特殊的窗口,即輸入法窗口和壁紙窗口,當(dāng)它們不是窗口堆棧底部的第一個(gè)窗口時(shí),它們所在的計(jì)算單元不是以窗口類型來(lái)劃分的,而靠近在哪 個(gè)窗口,就與哪個(gè)窗口在同一個(gè)計(jì)算單元中。當(dāng)輸入法窗口是窗口堆棧底部的第一個(gè)窗口時(shí),它的Z軸位置就等于 WINDOW_LAYER_MULTIPLIER,而當(dāng)壁紙窗口是窗口堆棧底部的第一個(gè)窗口時(shí),它的Z軸位置就等于它的BaseLayer值。

? ? ? ??前面計(jì)算得到的窗口的Z軸位置保存在WindowState類的成員變量mLayer中。事實(shí)上,保存在WindowState類的成員變量 mLayer中的Z軸位置還不是窗口的最終Z軸位置,因?yàn)檫€沒(méi)有考慮到窗口與窗口令牌之間的關(guān)系。每一個(gè)窗口令牌都可以設(shè)置一個(gè)Z軸調(diào)整值,而每一個(gè)窗口 要加上它所對(duì)應(yīng)的窗口令牌所設(shè)置的Z軸調(diào)整值之后,才能得到最終的Z軸位置。注意,只有類型為AppWindowToken的窗口令牌才可以設(shè)置Z軸調(diào)整 值,這個(gè)Z軸調(diào)整值就保存在AppWindowToken類的成員變量animLayerAdjustment中。

? ? ? ? 有時(shí)候,一個(gè)窗口會(huì)有一個(gè)目標(biāo)窗口。例如,輸入法窗口的目標(biāo)窗口是系統(tǒng)當(dāng)前需要顯示輸入法的窗口。在這種情況下,我們要使用目標(biāo)窗口所對(duì)應(yīng)的窗口令牌所設(shè)置的Z軸調(diào)整值來(lái)調(diào)整窗口的的Z軸位置。

? ? ? ? 那么,WindowManagerService服務(wù)是如何知道一個(gè)窗口所對(duì)應(yīng)的窗口令牌的類型是AppWindowToken,或者一個(gè)窗口有沒(méi)有目標(biāo) 窗口的呢?當(dāng)用來(lái)描述一個(gè)窗口的WindowState對(duì)象成員變量mAppToken的值不等于null的時(shí)候,那么就說(shuō)明該窗口所對(duì)應(yīng)的窗口令牌的類 型是AppWindowToken,而當(dāng)用來(lái)描述一個(gè)窗口的WindowState對(duì)象成員變量mTargetAppToken的值不等于null的時(shí) 候,那么就說(shuō)明該窗口有一個(gè)目標(biāo)窗口。

? ? ? ? 經(jīng)過(guò)上面的調(diào)整之后,窗口的Z軸位置就保存在WindowState類的成員變量mAnimLayer中。對(duì)于非輸入法窗口和非壁紙窗口來(lái)說(shuō),這時(shí)候保存 在用來(lái)描述它們的WindowState對(duì)象的成員變量mAnimLayer中的Z軸位置就是它們最終的Z軸位置了,但是對(duì)于輸入法窗口和壁紙窗口來(lái)說(shuō), 還需要繼續(xù)判斷它們的目標(biāo)窗口是否需要調(diào)整它們的Z軸位置。

? ? ? ? 從前面Android窗口管理服務(wù)WindowManagerService對(duì)壁紙窗口(Wallpaper Window)的管理分析和Android窗口管理服務(wù)WindowManagerService對(duì)輸入法窗口(Input Method Window)的管理分析這 兩篇文章知道,如果一個(gè)窗口要調(diào)整它所關(guān)聯(lián)的輸入法窗口和壁紙窗口的Z軸位置,那么要調(diào)整的值就會(huì)保存在WindowManagerService類的成 員變量mInputMethodAnimLayerAdjustment和mWallpaperAnimLayerAdjustment中,因此,只要將 WindowManagerService類的成員變量mInputMethodAnimLayerAdjustment和 mWallpaperAnimLayerAdjustment的值分別增加到前面所計(jì)算得到的輸入法窗口和壁紙窗口的Z軸位置上去,就可以得到輸入法窗口 和壁紙窗口的最終Z軸位置,并且保存到用來(lái)對(duì)應(yīng)的WindowState對(duì)象的成員變量mAnimLayer中。

? ? ? ? 從上面的計(jì)算過(guò)程就可以知道,系統(tǒng)中所有類型的窗口的最終Z軸位置都保存在WindowState類的成員變量mAnimLayer中。

? ? ? ? 三. 設(shè)置窗口的Z軸位置到SurfaceFlinger服務(wù)中去

? ? ? ? WindowManagerService服務(wù)在刷新系統(tǒng)的UI的時(shí)候,就會(huì)將系統(tǒng)中已經(jīng)計(jì)算好了的窗口Z軸位置設(shè)置到SurfaceFlinger服務(wù)中去,以便SurfaceFlinger服務(wù)可以對(duì)系統(tǒng)中的窗口進(jìn)行可見(jiàn)性計(jì)算以及合成和渲染等操作。

? ? ? ? 從前面Android窗口管理服務(wù)WindowManagerService計(jì)算Activity窗口大小的過(guò)程分析一 文可以知道,刷新系統(tǒng)UI是通過(guò)調(diào)用WindowManagerService類的成員函數(shù) performLayoutAndPlaceSurfacesLockedInner來(lái)實(shí)現(xiàn)的,接下來(lái)我們就分析這個(gè)成員函數(shù)與設(shè)置窗口的Z軸位置到 SurfaceFlinger服務(wù)中去相關(guān)的邏輯。

? ? ? ? 為了方便描述設(shè)置窗口的Z軸位置到SurfaceFlinger服務(wù)中去的過(guò)程,我們先列出WindowManagerService類的成員函數(shù)performLayoutAndPlaceSurfacesLockedInner的實(shí)現(xiàn)架構(gòu),如下所示:

[java] view plaincopy
  1. public?class?WindowManagerService?extends?IWindowManager.Stub????
  2. ????????implements?Watchdog.Monitor?{????
  3. ????......????
  4. ????
  5. ????private?final?void?performLayoutAndPlaceSurfacesLockedInner(????
  6. ????????????boolean?recoveringMemory)?{????
  7. ????????......????
  8. ????
  9. ????????Surface.openTransaction();????
  10. ????????......????
  11. ????
  12. ????????try?{????
  13. ????????????......????
  14. ????????????int?repeats?=?0;????
  15. ????????????int?changes?=?0;????
  16. ????????????????
  17. ????????????do?{????
  18. ????????????????repeats++;????
  19. ????????????????if?(repeats?>?6)?{????
  20. ????????????????????......????
  21. ????????????????????break;????
  22. ????????????????}????
  23. ????
  24. ????????????????//?FIRST?LOOP:?Perform?a?layout,?if?needed.????
  25. ????????????????if?(repeats?<?4)?{????
  26. ????????????????????changes?=?performLayoutLockedInner();????
  27. ????????????????????if?(changes?!=?0)?{????
  28. ????????????????????????continue;????
  29. ????????????????????}????
  30. ????????????????}?else?{????
  31. ????????????????????Slog.w(TAG,?"Layout?repeat?skipped?after?too?many?iterations");????
  32. ????????????????????changes?=?0;????
  33. ????????????????}????
  34. ????
  35. ????????????????//?SECOND?LOOP:?Execute?animations?and?update?visibility?of?windows.????
  36. ????????????????......????
  37. ????????????????????
  38. ????????????}?while?(changes?!=?0);????
  39. ????
  40. ????????????//?THIRD?LOOP:?Update?the?surfaces?of?all?windows.???
  41. ????????????......??
  42. ??
  43. ????????????//更新窗口的繪圖表面的操作包括:??
  44. ????????????//1.?設(shè)置窗口的大小??
  45. ????????????//2.?設(shè)置窗口在X軸和Y軸上的位置??
  46. ????????????//3.?設(shè)置窗口在Z軸上的位置??
  47. ????????????//4.?設(shè)置窗口的Alpha通道??
  48. ????????????//5.?設(shè)置窗口的變換矩陣??
  49. ????????????......??
  50. ?????????????????????
  51. ????????}?catch?(RuntimeException?e)?{????
  52. ????????????......????
  53. ????????}????
  54. ????
  55. ????????......????
  56. ????
  57. ????????Surface.closeTransaction();????
  58. ????
  59. ????????......????
  60. ????
  61. ????????//?Destroy?the?surface?of?any?windows?that?are?no?longer?visible.????
  62. ????????......????
  63. ????
  64. ????????//?Time?to?remove?any?exiting?tokens?????
  65. ????????......????
  66. ????
  67. ????????//?Time?to?remove?any?exiting?applications?????
  68. ????????......????
  69. ????}????
  70. ????
  71. ????......????
  72. }????

? ? ? ??這個(gè)函數(shù)定義在文件frameworks/base/services/java/com/android/server/WindowManagerService.java中。

? ? ? ? 在前面Android窗口管理服務(wù)WindowManagerService計(jì)算Activity窗口大小的過(guò)程分析一 文中,我們已經(jīng)分析過(guò)WindowManagerService類的成員函數(shù) performLayoutAndPlaceSurfacesLockedInner的實(shí)現(xiàn)架構(gòu)了,其中,設(shè)置窗口的Z軸位置到 SurfaceFlinger服務(wù)中去是在更新窗口的繪圖表面的操作中進(jìn)行的,即是在THIRD LOOP中進(jìn)行的,同時(shí)設(shè)置的還包括窗口的大小、X軸和Y軸位置、Alpha通道和變換矩陣,這些代碼如下所示:

[java] view plaincopy
  1. //更新窗口的繪圖表面的操作包括:??
  2. //1.?設(shè)置窗口的大小??
  3. //2.?設(shè)置窗口在X軸和Y軸上的位置??
  4. //3.?設(shè)置窗口在Z軸上的位置??
  5. //4.?設(shè)置窗口的Alpha通道值??
  6. //5.?設(shè)置窗口的變換矩陣??
  7. final?int?N?=?mWindows.size();??
  8. ??
  9. for?(i=N-1;?i>=0;?i--)?{??
  10. ????WindowState?w?=?mWindows.get(i);???
  11. ????......??
  12. ??
  13. ????if?(w.mSurface?!=?null)?{??
  14. ????????......??
  15. ??
  16. ????????w.computeShownFrameLocked();??
  17. ????????......??
  18. ??
  19. ????????boolean?resize;??
  20. ????????int?width,?height;??
  21. ????????if?((w.mAttrs.flags?&?w.mAttrs.FLAG_SCALED)?!=?0)?{??
  22. ????????????resize?=?w.mLastRequestedWidth?!=?w.mRequestedWidth?||??
  23. ????????????w.mLastRequestedHeight?!=?w.mRequestedHeight;??
  24. ????????????//?for?a?scaled?surface,?we?just?want?to?use??
  25. ????????????//?the?requested?size.??
  26. ????????????width??=?w.mRequestedWidth;??
  27. ????????????height?=?w.mRequestedHeight;??
  28. ????????????w.mLastRequestedWidth?=?width;??
  29. ????????????w.mLastRequestedHeight?=?height;??
  30. ????????????w.mLastShownFrame.set(w.mShownFrame);??
  31. ????????????try?{??
  32. ????????????????......??
  33. ????????????????w.mSurfaceX?=?w.mShownFrame.left;??
  34. ????????????????w.mSurfaceY?=?w.mShownFrame.top;??
  35. ????????????????w.mSurface.setPosition(w.mShownFrame.left,?w.mShownFrame.top);??
  36. ????????????}?catch?(RuntimeException?e)?{??
  37. ????????????????......??
  38. ????????????????if?(!recoveringMemory)?{??
  39. ????????????????????reclaimSomeSurfaceMemoryLocked(w,?"position");??
  40. ????????????????}??
  41. ????????????}??
  42. ????????}?else?{??
  43. ????????????resize?=?!w.mLastShownFrame.equals(w.mShownFrame);??
  44. ????????????width?=?w.mShownFrame.width();??
  45. ????????????height?=?w.mShownFrame.height();??
  46. ????????????w.mLastShownFrame.set(w.mShownFrame);??
  47. ????????}??
  48. ??
  49. ????????if?(resize)?{??
  50. ????????????if?(width?<?1)?width?=?1;??
  51. ????????????if?(height?<?1)?height?=?1;??
  52. ????????????if?(w.mSurface?!=?null)?{??
  53. ????????????????try?{??
  54. ????????????????????......??
  55. ????????????????????w.mSurfaceResized?=?true;??
  56. ????????????????????w.mSurfaceW?=?width;??
  57. ????????????????????w.mSurfaceH?=?height;??
  58. ????????????????????w.mSurface.setSize(width,?height);??
  59. ????????????????????w.mSurfaceX?=?w.mShownFrame.left;??
  60. ????????????????????w.mSurfaceY?=?w.mShownFrame.top;??
  61. ????????????????????w.mSurface.setPosition(w.mShownFrame.left,??
  62. ????????????????????????????w.mShownFrame.top);??
  63. ????????????????}?catch?(RuntimeException?e)?{??
  64. ????????????????????......??
  65. ????????????????????if?(!recoveringMemory)?{??
  66. ????????????????????????reclaimSomeSurfaceMemoryLocked(w,?"size");??
  67. ????????????????????}??
  68. ????????????????}??
  69. ????????????}??
  70. ????????}??
  71. ??
  72. ????????......??
  73. ??
  74. ????????if?(w.mAttachedHidden?||?!w.isReadyForDisplay())?{??
  75. ????????????if?(!w.mLastHidden)?{??
  76. ????????????????w.mLastHidden?=?true;??
  77. ????????????????......??
  78. ??
  79. ????????????????if?(w.mSurface?!=?null)?{??
  80. ????????????????????w.mSurfaceShown?=?false;??
  81. ????????????????????try?{??
  82. ????????????????????????w.mSurface.hide();??
  83. ????????????????????}?catch?(RuntimeException?e)?{??
  84. ????????????????????????......??
  85. ????????????????????}??
  86. ????????????????}??
  87. ????????????}????
  88. ??
  89. ????????????......??
  90. ????????}?else?if?(w.mLastLayer?!=?w.mAnimLayer??
  91. ????????????????||?w.mLastAlpha?!=?w.mShownAlpha??
  92. ????????????????||?w.mLastDsDx?!=?w.mDsDx??
  93. ????????????????||?w.mLastDtDx?!=?w.mDtDx??
  94. ????????????????||?w.mLastDsDy?!=?w.mDsDy??
  95. ????????????????||?w.mLastDtDy?!=?w.mDtDy??
  96. ????????????????||?w.mLastHScale?!=?w.mHScale??
  97. ????????????????||?w.mLastVScale?!=?w.mVScale??
  98. ????????????????||?w.mLastHidden)?{??????
  99. ????????????......??
  100. ????????????w.mLastAlpha?=?w.mShownAlpha;??
  101. ????????????w.mLastLayer?=?w.mAnimLayer;??
  102. ????????????w.mLastDsDx?=?w.mDsDx;??
  103. ????????????w.mLastDtDx?=?w.mDtDx;??
  104. ????????????w.mLastDsDy?=?w.mDsDy;??
  105. ????????????w.mLastDtDy?=?w.mDtDy;??
  106. ????????????w.mLastHScale?=?w.mHScale;??
  107. ????????????w.mLastVScale?=?w.mVScale;??
  108. ????????????......??
  109. ????????????if?(w.mSurface?!=?null)?{??
  110. ???????????????try?{??
  111. ????????????????????w.mSurfaceAlpha?=?w.mShownAlpha;??
  112. ????????????????????w.mSurface.setAlpha(w.mShownAlpha);??
  113. ????????????????????w.mSurfaceLayer?=?w.mAnimLayer;??
  114. ????????????????????w.mSurface.setLayer(w.mAnimLayer);??
  115. ????????????????????w.mSurface.setMatrix(??
  116. ????????????????????????????w.mDsDx*w.mHScale,?w.mDtDx*w.mVScale,??
  117. ????????????????????????????w.mDsDy*w.mHScale,?w.mDtDy*w.mVScale);??
  118. ????????????????}?catch?(RuntimeException?e)?{??
  119. ????????????????????.....??
  120. ????????????????????if?(!recoveringMemory)?{??
  121. ????????????????????????reclaimSomeSurfaceMemoryLocked(w,?"update");??
  122. ????????????????????}??
  123. ????????????????}??
  124. ????????????}??
  125. ??
  126. ????????????if?(w.mLastHidden?&&?!w.mDrawPending??
  127. ????????????????????&&?!w.mCommitDrawPending??
  128. ????????????????????&&?!w.mReadyToShow)?{??
  129. ????????????????......??
  130. ????????????????if?(showSurfaceRobustlyLocked(w))?{??
  131. ????????????????????w.mHasDrawn?=?true;??
  132. ????????????????????w.mLastHidden?=?false;??
  133. ????????????????}???
  134. ????????}????
  135. ??
  136. ????????......??
  137. ????}??
  138. ??
  139. ????......????????????????????????????
  140. }??

? ? ? ? 這段代碼通過(guò)一個(gè)for循環(huán)來(lái)遍歷保存在窗口堆棧的每一個(gè)WindowState對(duì)象,以便可以對(duì)系統(tǒng)中的每一個(gè)窗口的繪圖表面進(jìn)行更新。注意,只有那些 成員變量mSurface的值不等于null的WindowState對(duì)象,它們所描述的窗口才具有繪圖表面,因此需要對(duì)它們進(jìn)行更新。

? ? ? ? 在更新WindowState對(duì)象w所描述的窗口的繪圖表面之前,首先要調(diào)用它的成員函數(shù)computeShownFrameLocked來(lái)確定該窗口實(shí)際要顯示的大小、位置、Alpha通道和變換矩陣等信息,其中:

? ? ? ? 1.?窗口實(shí)際要顯示的大小和X軸、Y軸位置保存在WindowState對(duì)象w的成員變量mShownFrame中。

? ? ? ? 2.?窗口實(shí)際要顯示的Alpha通道保存在WindowState對(duì)象w的成員變量mShownAlpha中。

? ? ? ? 3.?窗口實(shí)際要顯示的Z軸位置保存在WindowState對(duì)象w的成員變量mAnimLayer中。

? ? ? ? 4.?窗口實(shí)際要使用的變換矩陣保存在WindowState對(duì)象w的成員變量mDsDx、mDtDx、mDsDy和mDtDy中。

? ? ? ? 有了上述信息之后,我們就可以將WindowState對(duì)象w所描述的窗口實(shí)際要顯示的大小、位置、Alpha通道和變換矩陣等信息設(shè)置到SurfaceFlinger服務(wù)中去了。

? ? ? ? 我們首先分析WindowState對(duì)象w所描述的窗口實(shí)際要顯示的大小、X軸和Y軸位置的設(shè)置過(guò)程,接著再分析WindowState對(duì)象w所描述的窗口實(shí)際要顯示的Alpha通道、Z軸位置以及實(shí)際要使用的變換矩陣的設(shè)置過(guò)程。

? ? ? ? 在調(diào)用WindowState對(duì)象w的成員函數(shù)computeShownFrameLocked來(lái)計(jì)算它所描述的窗口的大小的時(shí)候,是沒(méi)有考慮該窗口的大小是否設(shè)置有縮放因子的。

? ? ? ? 當(dāng)WindowState對(duì)象w所描述的窗口的大小設(shè)置有縮放因子的時(shí)候,那么WindowState對(duì)象w的成員變量mAttrs所指向的一個(gè) WindowManager.LayoutParams對(duì)象的成員變量flags的FLAG_SCALED位就會(huì)等于1,這時(shí)候WindowState對(duì) 象w所描述的窗口實(shí)際要顯示的大小是保存在它的成員變量mRequestedWidth和mRequestedHeight中的。在這種情況下,這段代碼 就會(huì)執(zhí)行以下操作:

? ? ? ? 1. 計(jì)算WindowState對(duì)象w所描述的窗口實(shí)際要顯示的大小是否發(fā)生了變化。如果發(fā)生了變化,那么就將變量resize的值設(shè)置為true。注 意,WindowState對(duì)象w所描述的窗口上一次實(shí)際要顯示的大小保存在成員變量mLastRequestedWidth和 mLastRequestedHeight中,因此,當(dāng)這兩個(gè)成員變量與其它兩個(gè)成員變量mRequestedWidth和 mRequestedHeight的值不相等于時(shí),就說(shuō)明WindowState對(duì)象w所描述的窗口實(shí)際要顯示的大小是否發(fā)生了變化。

? ? ? ? 2. 將WindowState對(duì)象w所描述的窗口實(shí)際要顯示的大小分別更新到成員變量mLastRequestedWidth和mLastRequestedHeight中,以及變量width和height中。

? ? ? ? 3. 將WindowState對(duì)象w的成員變量mShownFrame的值保存在另外一個(gè)成員變量mLastShownFrame中,以便可以記錄WindowState對(duì)象w所描述的窗口上一次實(shí)際要顯示的大小和X軸、Y軸位置。

? ? ? ? 4. 將WindowState對(duì)象w所描述的窗口的X軸和Y軸位置分別保存到成員變量mSurfaceX和mSurfaceY中,并且調(diào)用 WindowState對(duì)象w的成員變量mSurface所指向的一個(gè)Surface對(duì)象的成員函數(shù)setPosition來(lái)將這兩個(gè)位置值設(shè)置到 SurfaceFlinger服務(wù)中去。

? ? ? ? 5. 在設(shè)置WindowState對(duì)象w所描述的窗口的X軸和Y軸位置到SurfaceFlinger服務(wù)中去的過(guò)程中,如果出現(xiàn)了異常,那么就說(shuō)明系統(tǒng)內(nèi)存 資源不足。在這種情況下,如果參數(shù)recoveringMemory的值等于false,那么就說(shuō)明WindowManagerService服務(wù)目前不 是處于內(nèi)存資源的回收過(guò)程中,于是就會(huì)調(diào)用WindowManagerService類的成員函數(shù) reclaimSomeSurfaceMemoryLocked來(lái)執(zhí)行回收系統(tǒng)內(nèi)存資源的操作。

? ? ? ??當(dāng)WindowState對(duì)象w所描述的窗口的大小沒(méi)有設(shè)置有縮放因子的時(shí)候,那么WindowState對(duì)象w的成員變量mAttrs所指向的一個(gè) WindowManager.LayoutParams對(duì)象的成員變量flags的FLAG_SCALED位就會(huì)等于0,這時(shí)候WindowState對(duì) 象w所描述的窗口實(shí)際要顯示的大小是保存在它的成員變量mShownFrame中的。在這種情況下,這段代碼就會(huì)執(zhí)行以下操作:

? ? ? ? 1.?計(jì)算WindowState對(duì)象w所描述的窗口實(shí)際要顯示的大小是否發(fā)生了變化。如果發(fā)生了變化,那么就將變量resize的值設(shè)置為true。注 意,這時(shí)候只要比較WindowState對(duì)象w的成員變量mLastShownFrame和mShownFrame所描述的兩個(gè)矩形區(qū)域的大小是否相 等,就可以知道WindowState對(duì)象w所描述的窗口實(shí)際要顯示的大小是否發(fā)生了變化,因?yàn)閃indowState對(duì)象w的成員變量 mLastShownFrame保存的是窗口上一次實(shí)際要顯示的大小。

? ? ? ? 2.?將WindowState對(duì)象w所描述的窗口實(shí)際要顯示的大小分別保存在變量width和height中。

? ? ? ? 3.?將WindowState對(duì)象w的成員變量mShownFrame的值保存在另外一個(gè)成員變量mLastShownFrame中,以便可以記錄WindowState對(duì)象w所描述的窗口上一次實(shí)際要顯示的大小和X軸、Y軸位置。

? ? ? ? 執(zhí)行完成以上操作之后,WindowState對(duì)象w所描述的窗口實(shí)際要顯示的X軸和Y軸位置就保存在成員變量mShownFrame所描述的一個(gè) Rect對(duì)象的成員變量left和top中,而實(shí)際要顯示的大小就顯示在變量width和height中。這時(shí)候如果變量resize的值等于true, 那么就說(shuō)明WindowState對(duì)象w所描述的窗口的大小發(fā)生了變化。在這種情況下,就需要執(zhí)行以下操作:

? ? ? ? 1. 重新設(shè)置WindowState對(duì)象w所描述的窗口的大小到SurfaceFlinger服務(wù)中去,這是通過(guò)調(diào)用WindowState對(duì)象w的成員變量 mSurface所指向的一個(gè)Surface對(duì)象的成員函數(shù)setSize來(lái)實(shí)現(xiàn)的。注意,如果前面計(jì)算得到WindowState對(duì)象w所描述的窗口的 寬度width和高度height的值小于1,那么就需要將它們的值設(shè)置為1,因?yàn)橐粋€(gè)窗口的寬度和高度值是不能小于1的。

? ? ? ? 2. 重新設(shè)置WindowState對(duì)象w所描述的窗口在X軸和Y軸上的位置到SurfaceFlinger服務(wù)中去,這是通過(guò)調(diào)用WindowState對(duì) 象w的成員變量mSurface所指向的一個(gè)Surface對(duì)象的成員函數(shù)setPosition來(lái)實(shí)現(xiàn)的。注意,在設(shè)置之前,還會(huì)將 WindowState對(duì)象w所描述的窗口在X軸和Y軸上的位置保存在成員變量mSurfaceX和mSurfaceY中。

? ? ? ? 3.?在設(shè)置WindowState對(duì)象w所描述的窗口的大小以及在X軸和Y軸上的位置到SurfaceFlinger服務(wù)中去的過(guò)程中,如果出現(xiàn)了異 常,那么同樣需要判斷參數(shù)recoveringMemory的值來(lái)決定是否需要WindowManagerService類的成員函數(shù) reclaimSomeSurfaceMemoryLocked來(lái)回收系統(tǒng)內(nèi)存資源。

? ? ? ? 設(shè)置好WindowState對(duì)象w所描述的窗口實(shí)際要顯示的大小、X軸和Y軸位置到SurfaceFlinger服務(wù)中去之后,接下來(lái)就要繼續(xù)設(shè)置它實(shí) 際要顯示的Alpha通道、Z軸位置以及實(shí)際要使用的變換矩陣了,不過(guò)只有當(dāng)WindowState對(duì)象w所描述的窗口當(dāng)前是處于可見(jiàn)狀態(tài)、并且這些值沒(méi) 有發(fā)生變化的情況下才需要這樣做。

? ? ? ? 當(dāng)WindowState對(duì)象w的成員函數(shù)isReadyForDisplay的返回值等于false時(shí),就說(shuō)明WindowState對(duì)象w所描述的窗 口當(dāng)前是處于不可見(jiàn)狀態(tài)的。還有另外一種情況,即當(dāng)WindowState對(duì)象w所描述的窗口是附加在另外一個(gè)窗口之上、并且這個(gè)被附加的窗口是不可見(jiàn) 時(shí),即WindowState對(duì)象w的成員變量mAttachedHidden的值等于true時(shí),也是說(shuō)明WindowState對(duì)象w所描述的窗口當(dāng) 前是處于不可見(jiàn)狀態(tài)的。

? ? ? ? 在WindowState對(duì)象w所描述的窗口當(dāng)前是處于不可見(jiàn)狀態(tài)的情況下,如果該窗口在上一次系統(tǒng)UI刷新時(shí)是處于可見(jiàn)狀態(tài)的,即 WindowState對(duì)象w的成員變量mLastHidden的值等于true,那么這時(shí)候就需要將WindowState對(duì)象w所描述的窗口隱藏起 來(lái),這是通過(guò)調(diào)用WindowState對(duì)象w的成員變量mSurface所指向的一個(gè)Surface對(duì)象的成員函數(shù)hide來(lái)實(shí)現(xiàn)的。注意,在調(diào)用 WindowState對(duì)象w的成員變量mSurface所指向的一個(gè)Surface對(duì)象的成員函數(shù)hide來(lái)隱藏窗口之前,需要分別將 WindowState對(duì)象w的成員變量mLastHidden和mSurfaceShown的值設(shè)置為true和false,以便可以正確描述窗口的不 可見(jiàn)狀態(tài)。

? ? ? ??在WindowState對(duì)象w所描述的窗口當(dāng)前是處于可見(jiàn)狀態(tài)的情況下,如果該窗口實(shí)際要顯示的Alpha通道、Z軸位置以及實(shí)際要使用的變換矩陣發(fā)生了變化,那么就需要將新的值設(shè)置到SurfaceFlinger服務(wù)中去,其中:

? ? ? ? 1.?WindowState對(duì)象w的成員變量mLastLayer與mAnimLayer的值不相等說(shuō)明它描述的窗口的Z軸位置發(fā)生了變化。

? ? ? ? 2.?WindowState對(duì)象w的成員變量mLastAlpha與mShownAlpha的值不相等說(shuō)明它描述的窗口的Alpha通道發(fā)生了變化。

? ? ? ? 3.?WindowState對(duì)象w的成員變量mLastDsDx、mLastDtDx、mLastDsDy、 mLastDtDy、mLastHScale、mLastVScale與成員變量mDsDx、mDtDx、mDsDy、?mDtDy、mHScale、 mVScale的值不相等說(shuō)明它描述的窗口的變換矩陣發(fā)生了變化。

? ? ? ??在WindowState對(duì)象w所描述的窗口當(dāng)前是處于可見(jiàn)狀態(tài)的情況下,如果該窗口在上一次系統(tǒng)UI刷新時(shí)是處于可見(jiàn)狀態(tài)的,即 WindowState對(duì)象w的成員變量mLastHidden的值等于true,那么也是需要重新設(shè)置WindowState對(duì)象w所描述的窗口實(shí)際要 顯示的Alpha通道、Z軸位置以及實(shí)際要使用的變換矩陣到SurfaceFlinger服務(wù)中去的。

? ? ? ? 無(wú)論如何,當(dāng)需要重新設(shè)置WindowState對(duì)象w所描述的窗口實(shí)際要顯示的Alpha通道、Z軸位置以及實(shí)際要使用的變換矩陣到SurfaceFlinger服務(wù)中去時(shí),就需要執(zhí)行以下操作:

? ? ? ? 1. 重新設(shè)置WindowState對(duì)象w所描述的窗口的Alpha通道到SurfaceFlinger服務(wù)中去,這是通過(guò)調(diào)用WindowState對(duì)象w 的成員變量mSurface所指向的一個(gè)Surface對(duì)象的成員函數(shù)setAlpha來(lái)實(shí)現(xiàn)的。在設(shè)置之前,還會(huì)將WindowState對(duì)象w的成員 變量mShownAlpha的值同時(shí)保存在成員變量mLastAlpha和mSurfaceAlpha中,以便可以記錄WindowState對(duì)象w所描 述的窗口上一次所使用的Alpha通道。

? ? ? ? 2.?重新設(shè)置WindowState對(duì)象w所描述的窗口的Z軸位置到SurfaceFlinger服務(wù)中去,這是通過(guò)調(diào)用WindowState對(duì)象w 的成員變量mSurface所指向的一個(gè)Surface對(duì)象的成員函數(shù)setLayer來(lái)實(shí)現(xiàn)的。在設(shè)置之前,還會(huì)將WindowState對(duì)象w的成員 變量mAnimLayer的值同時(shí)保存在成員變量mLastLayer和mSurfaceLayer中,以便可以記錄WindowState對(duì)象w所描述 的窗口上一次所使用的Z軸位置。

? ? ? ? 3.?重新設(shè)置WindowState對(duì)象w所描述的窗口的變換矩陣到SurfaceFlinger服務(wù)中去,這是通過(guò)調(diào)用WindowState對(duì)象w 的成員變量mSurface所指向的一個(gè)Surface對(duì)象的成員函數(shù)setMatrix來(lái)實(shí)現(xiàn)的。在設(shè)置之前,還會(huì)將WindowState對(duì)象w的成 員變量成員變量mDsDx、mDtDx、mDsDy、?mDtDy、mHScale、mVScale的值分別保存在成員變量mLastDsDx、 mLastDtDx、mLastDsDy、?mLastDtDy、mLastHScale、mLastVScale中,以便可以記錄 WindowState對(duì)象w所描述的窗口上一次所使用的變換矩陣。注意,WindowState對(duì)象的成員變量mHScale和mVScale描述的窗 口在寬度和高度上的縮放因子,因此,在設(shè)置窗口的變換矩陣時(shí),需要乘以這些因子才可以得到正確的變換矩陣參數(shù)。

? ? ? ? 4.?在設(shè)置WindowState對(duì)象w所描述的窗口的Alpha通道、Z軸位置以及實(shí)際要使用的變換矩陣到SurfaceFlinger服務(wù)的過(guò)程 中,如果出現(xiàn)了異常,那么同樣需要判斷參數(shù)recoveringMemory的值來(lái)決定是否需要WindowManagerService類的成員函數(shù) reclaimSomeSurfaceMemoryLocked來(lái)回收系統(tǒng)內(nèi)存資源。

? ? ? ? 將WindowState對(duì)象w所描述的窗口實(shí)際要顯示的Alpha通道、Z軸位置以及實(shí)際要使用的變換矩陣設(shè)置到SurfaceFlinger服務(wù)之后,如果WindowState對(duì)象w所描述的窗口滿足以下條件:

? ? ? ? 1. 上一次處于不可見(jiàn)狀態(tài),即WindowState對(duì)象w的成員變量mLastHidden的值等于true;

? ? ? ? 2. UI已經(jīng)繪制完成,即WindowState對(duì)象w的成員變量mDrawPending和mCommitDrawPending值等于false;

? ? ? ? 3. 不是處于等待同一個(gè)窗口令牌的其它窗口的完成UI繪制的狀態(tài),即WindowState對(duì)象w的成員變量mReadyToShow的值等于false;

? ? ? ? 那么就說(shuō)明現(xiàn)在就是時(shí)候要將WindowState對(duì)象w所描述的窗口顯示出來(lái)了,這是通過(guò)調(diào)用WindowManagerService類的成員函數(shù) showSurfaceRobustlyLocked來(lái)實(shí)現(xiàn)的。如果WindowManagerService類的成員函數(shù) showSurfaceRobustlyLocked的返回值等于true,那么就說(shuō)明WindowManagerService服務(wù)已經(jīng)成功地通知 SurfaceFlinger服務(wù)將WindowState對(duì)象w所描述的窗口顯示出來(lái),于是就會(huì)分別將WindowState對(duì)象w的成員變量 mHasDrawn和mLastHidden的值設(shè)置為true和false,以便可以表示W(wǎng)indowState對(duì)象w所描述的窗口的UI已經(jīng)繪制完 成,并且已經(jīng)顯示出來(lái)。

? ? ? ??WindowManagerService類的成員函數(shù)showSurfaceRobustlyLocked的實(shí)現(xiàn)如下所示:

[java] view plaincopy
  1. public?class?WindowManagerService?extends?IWindowManager.Stub????
  2. ????????implements?Watchdog.Monitor?{????
  3. ????......????
  4. ????
  5. ????boolean?showSurfaceRobustlyLocked(WindowState?win)?{??
  6. ????????try?{??
  7. ????????????if?(win.mSurface?!=?null)?{??
  8. ????????????????win.mSurfaceShown?=?true;??
  9. ????????????????win.mSurface.show();??
  10. ????????????????......??
  11. ????????????}??
  12. ????????????return?true;??
  13. ????????}?catch?(RuntimeException?e)?{??
  14. ????????????......??
  15. ????????}??
  16. ??
  17. ????????reclaimSomeSurfaceMemoryLocked(win,?"show");??
  18. ??
  19. ????????return?false;??
  20. ????}??
  21. ????
  22. ????......????
  23. }????

? ? ? ??這個(gè)函數(shù)定義在文件frameworks/base/services/java/com/android/server/WindowManagerService.java中。

? ? ? ??WindowManagerService類的成員函數(shù)showSurfaceRobustlyLocked用來(lái)通知SurfaceFlinger服 務(wù)將參數(shù)win所描述的窗口顯示出來(lái),這是通過(guò)調(diào)用WindowState對(duì)象win的成員變量mSurface所指向的一個(gè)Surface對(duì)象的成員函 數(shù)show來(lái)實(shí)現(xiàn)的。注意,在通知SurfaceFlinger服務(wù)將WindowState對(duì)象win所描述的窗口顯示出來(lái)之前,還會(huì)將它的成員變量 mSurfaceShown的值設(shè)置為true。

? ? ? ? 如果在通知SurfaceFlinger服務(wù)將WindowState對(duì)象win所描述的窗口顯示出來(lái)的過(guò)程出現(xiàn)了異常,那么 WindowManagerService類的成員函數(shù)showSurfaceRobustlyLocked就會(huì)調(diào)用另外一個(gè)成員函數(shù) reclaimSomeSurfaceMemoryLocked來(lái)回收系統(tǒng)內(nèi)存資源。

? ? ? ? 從上面分析可以知道,一個(gè)窗口的顯示和隱藏,以及大小、X軸和Y軸位置、Z軸位置、Alpha通道和變換矩陣設(shè)置,是通過(guò)調(diào)用Java層的Surface 類的成員函數(shù)show、hide、setSize、setPosition、setLayer、setAlpha和setMatrix來(lái)實(shí)現(xiàn)的,它們都是 一些JNI方法,定義在文件frameworks/base/core/java/android/view/Surface.java中,如下所示:

[java] view plaincopy
  1. public?class?Surface?implements?Parcelable?{??
  2. ????......??
  3. ??
  4. ????private?int?mSurfaceControl;??
  5. ????......??
  6. ??
  7. ????/**?
  8. ?????*?set?surface?parameters.?
  9. ?????*?needs?to?be?inside?open/closeTransaction?block?
  10. ?????*/??
  11. ????public?native???void?setLayer(int?zorder);??
  12. ????public?native???void?setPosition(int?x,?int?y);??
  13. ????public?native???void?setSize(int?w,?int?h);??
  14. ??
  15. ????public?native???void?hide();??
  16. ????public?native???void?show();??
  17. ????......??
  18. ????public?native???void?setAlpha(float?alpha);??
  19. ????public?native???void?setMatrix(float?dsdx,?float?dtdx,??
  20. ???????????????????????????????????float?dsdy,?float?dtdy);??
  21. ????......??
  22. ??
  23. }??

? ? ? ?這些JNI方法是由C++層中的函數(shù)Surface_show、Surface_hide、Surface_setSize、 Surface_setPosition、Surface_setLayer、Surface_setAlpha和Surface_setMatrix來(lái) 實(shí)現(xiàn)的,如下所示:

[cpp] view plaincopy
  1. static?void?Surface_setLayer(??
  2. ????????JNIEnv*?env,?jobject?clazz,?jint?zorder)??
  3. {??
  4. ????const?sp<SurfaceControl>&?surface(getSurfaceControl(env,?clazz));??
  5. ????if?(surface?==?0)?return;??
  6. ????status_t?err?=?surface->setLayer(zorder);??
  7. ????if?(err<0?&&?err!=NO_INIT)??
  8. ????????doThrow(env,?"java/lang/IllegalArgumentException",?NULL);??
  9. }??
  10. ??
  11. static?void?Surface_setPosition(??
  12. ????????JNIEnv*?env,?jobject?clazz,?jint?x,?jint?y)??
  13. {??
  14. ????const?sp<SurfaceControl>&?surface(getSurfaceControl(env,?clazz));??
  15. ????if?(surface?==?0)?return;??
  16. ????status_t?err?=?surface->setPosition(x,?y);??
  17. ????if?(err<0?&&?err!=NO_INIT)??
  18. ????????doThrow(env,?"java/lang/IllegalArgumentException",?NULL);??
  19. }??
  20. ??
  21. static?void?Surface_setSize(??
  22. ????????JNIEnv*?env,?jobject?clazz,?jint?w,?jint?h)??
  23. {??
  24. ????const?sp<SurfaceControl>&?surface(getSurfaceControl(env,?clazz));??
  25. ????if?(surface?==?0)?return;??
  26. ????status_t?err?=?surface->setSize(w,?h);??
  27. ????if?(err<0?&&?err!=NO_INIT)??
  28. ????????doThrow(env,?"java/lang/IllegalArgumentException",?NULL);??
  29. }??
  30. ??
  31. static?void?Surface_hide(??
  32. ????????JNIEnv*?env,?jobject?clazz)??
  33. {??
  34. ????const?sp<SurfaceControl>&?surface(getSurfaceControl(env,?clazz));??
  35. ????if?(surface?==?0)?return;??
  36. ????status_t?err?=?surface->hide();??
  37. ????if?(err<0?&&?err!=NO_INIT)??
  38. ????????doThrow(env,?"java/lang/IllegalArgumentException",?NULL);??
  39. }??
  40. ??
  41. static?void?Surface_show(??
  42. ????????JNIEnv*?env,?jobject?clazz)??
  43. {??
  44. ????const?sp<SurfaceControl>&?surface(getSurfaceControl(env,?clazz));??
  45. ????if?(surface?==?0)?return;??
  46. ????status_t?err?=?surface->show();??
  47. ????if?(err<0?&&?err!=NO_INIT)??
  48. ????????doThrow(env,?"java/lang/IllegalArgumentException",?NULL);??
  49. }??
  50. ??
  51. static?void?Surface_setAlpha(??
  52. ????????JNIEnv*?env,?jobject?clazz,?jfloat?alpha)??
  53. {??
  54. ????const?sp<SurfaceControl>&?surface(getSurfaceControl(env,?clazz));??
  55. ????if?(surface?==?0)?return;??
  56. ????status_t?err?=?surface->setAlpha(alpha);??
  57. ????if?(err<0?&&?err!=NO_INIT)??
  58. ????????doThrow(env,?"java/lang/IllegalArgumentException",?NULL);??
  59. }??
  60. ??
  61. static?void?Surface_setMatrix(??
  62. ????????JNIEnv*?env,?jobject?clazz,??
  63. ????????jfloat?dsdx,?jfloat?dtdx,?jfloat?dsdy,?jfloat?dtdy)??
  64. {??
  65. ????const?sp<SurfaceControl>&?surface(getSurfaceControl(env,?clazz));??
  66. ????if?(surface?==?0)?return;??
  67. ????status_t?err?=?surface->setMatrix(dsdx,?dtdx,?dsdy,?dtdy);??
  68. ????if?(err<0?&&?err!=NO_INIT)??
  69. ????????doThrow(env,?"java/lang/IllegalArgumentException",?NULL);??
  70. }??

? ? ? ? 這些JNI方法定義在文件frameworks/base/core/jni/android_view_Surface.cpp中。

? ? ? ? 這些JNI都有一個(gè)共同的特點(diǎn),即先調(diào)用函數(shù)getSurfaceControl來(lái)獲得與參數(shù)clazz所描述的一個(gè)Java層的Surface對(duì)象所對(duì) 應(yīng)的一個(gè)SurfaceControl對(duì)象。有了這個(gè)SurfaceControl對(duì)象之后,就可以分別調(diào)用它的成員函數(shù)show、hide、 setSize、setPosition、setLayer、setAlpha和setMatrix來(lái)通知SurfaceFlinger服務(wù)來(lái)顯示和隱藏 一個(gè)窗口,以及設(shè)置一個(gè)窗口大小、X軸和Y軸位置、Z軸位置、Alpha通道和變換矩陣。

? ? ? ? 從前面Android應(yīng)用程序窗口(Activity)的繪圖表面(Surface)的創(chuàng)建過(guò)程分析一 文可以知道,每一個(gè)Activity窗口在Java層都對(duì)應(yīng)有兩個(gè)Surface對(duì)象,其中一個(gè)位于應(yīng)用程序進(jìn)程這一側(cè),而另外一個(gè)位于 WindowManagerService服務(wù)這一側(cè)。每一個(gè)位于應(yīng)用程序進(jìn)程這一側(cè)的Java層的Surface對(duì)象在C++層中都對(duì)應(yīng)有一個(gè) Surface對(duì)象,而每一個(gè)位于WindowManagerService服務(wù)這一側(cè)的Java層的Surface對(duì)象在C++層中都對(duì)應(yīng)有一個(gè) SurfaceControl對(duì)象,這個(gè)C++層的SurfaceControl對(duì)象的地址就保存在Java層的Surface對(duì)象的成員變量 mSurfaceControl中。

? ? ? ?從上面的分析可以知道,我們目前正在操作的是正在位于WindowManagerService服務(wù)這一側(cè)的Java層的Surface對(duì)象,因此,通 過(guò)調(diào)用函數(shù)getSurfaceControl就可以在C++層中獲得一個(gè)對(duì)應(yīng)的SurfaceControl對(duì)象,而有了這個(gè) SurfaceControl對(duì)象之后,就可以用來(lái)通知SurfaceFlinger服務(wù)更新一個(gè)窗口的屬性,這一點(diǎn)可以參考前面Android應(yīng)用程序與SurfaceFlinger服務(wù)的關(guān)系概述和學(xué)習(xí)計(jì)劃和Android系統(tǒng)Surface機(jī)制的SurfaceFlinger服務(wù)簡(jiǎn)要介紹和學(xué)習(xí)計(jì)劃兩個(gè)系列的文章。

? ? ? ?至此,WindowManagerService服務(wù)計(jì)算窗口Z軸位置的過(guò)程就分析完成了,這個(gè)過(guò)程如下所示:

? ? ? ?1.?WindowManagerService服務(wù)將窗口排列在一個(gè)窗口堆棧中;

? ? ? ?2.?WindowManagerService服務(wù)根據(jù)窗口類型以及窗口在窗口堆棧的位置來(lái)計(jì)算得窗口的Z軸位置;

? ? ? ?3.?WindowManagerService服務(wù)通過(guò)Java層的Surface類的成員函數(shù)setLayer來(lái)將窗口的Z軸位置設(shè)置到SurfaceFlinger服務(wù)中去;

? ? ? ?4. Java層的Surface類的成員函數(shù)setLayer又是通過(guò)調(diào)用C++層的SurfaceControl類的成員函數(shù)setLayer來(lái)將窗口的Z軸位置設(shè)置到SurfaceFlinger服務(wù)中去的;

? ? ? ?通過(guò)這篇文章以及前面三篇文章(窗口組織、輸入法窗口、壁紙窗口) 的學(xué)習(xí),我們對(duì)WindowManagerService服務(wù)對(duì)窗口的管理就有一個(gè)比較深刻的認(rèn)識(shí)了,在接下來(lái)的文章中,我們還將繼續(xù)分析 ActivityWindowManager服務(wù)和WindowManagerService服務(wù)是如何協(xié)作來(lái)完成Activity窗口的顯示過(guò)程的,敬 請(qǐng)關(guān)注!

老羅的新浪微博:http://weibo.com/shengyangluo,歡迎關(guān)注!

轉(zhuǎn)載于:https://www.cnblogs.com/Free-Thinker/p/4143189.html

總結(jié)

以上是生活随笔為你收集整理的Android窗口管理服务WindowManagerService计算窗口Z轴位置的过程分析的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。

www.久久久com | 国产一区黄色 | 久久精品欧美 | aa一级片 | 色成人亚洲 | 黄色三级免费片 | 婷婷色影院| 亚洲成熟女人毛片在线 | 成人黄色大片在线观看 | 欧洲精品码一区二区三区免费看 | 日韩午夜高清 | 久久福利| 色av网站 | 久久一区91 | 美女视频黄的免费的 | 久久久蜜桃 | 青草视频在线播放 | 超级碰碰视频 | 国产免费高清 | 成人a级黄色片 | 国产黄色精品在线 | 五月婷婷在线视频观看 | 国产黄大片在线观看 | 啪啪免费观看网站 | 久久久久五月 | 欧美精品亚洲精品日韩精品 | 久久成人国产精品一区二区 | av在线免费在线观看 | 国产精品美女久久久 | 日韩精品一区二区不卡 | 超碰97人人干 | 激情视频免费在线 | 久久久久久久久久久高潮一区二区 | 高清视频一区 | 成人在线视频你懂的 | 国产精品免费观看视频 | 国产精品久久久久久模特 | 亚洲精品电影在线 | av亚洲产国偷v产偷v自拍小说 | 日韩在线免费不卡 | 热久在线| 视频高清 | 欧美动漫一区二区三区 | 在线播放精品一区二区三区 | 97在线精品国自产拍中文 | 久久精品视频18 | av青草| 夜夜夜夜操 | bbbb操bbbb| 视频国产精品 | 91九色精品女同系列 | 在线观看福利网站 | 在线观看成人网 | 一级久久久 | 精品一区在线看 | 欧美另类sm图片 | 国产一区高清在线观看 | 精品免费在线视频 | 天天色天天射天天综合网 | 亚洲精品久久久蜜桃 | 18久久久久 | 狠狠狠狠干| 国产精品视频资源 | 97成人资源 | 日韩免费在线观看网站 | 久久免费国产视频 | av在线8 | 色射色| 亚洲精品免费播放 | 久久精品国产第一区二区三区 | 日韩中文字幕a | 久久亚洲精品国产亚洲老地址 | 日日日日| av软件在线观看 | 国产精品一区二区av麻豆 | 婷婷丁香久久五月婷婷 | 久久精品视频国产 | 久久久久久久久久久久99 | 久久综合五月天 | 九九热在线免费观看 | 天天天天色综合 | 香蕉成人在线视频 | 久久国产热视频 | 久久久久久久久久久久电影 | 久久成人麻豆午夜电影 | 天天干天天操天天 | 99久久精品无码一区二区毛片 | 久久精品久久久久久久 | 一区在线观看视频 | 五月天中文字幕mv在线 | 久久情爱 | 国产精品九九视频 | 亚洲精品系列 | 97视频久久久 | 亚洲精品国产日韩 | 欧美日韩中文视频 | 精品久久五月天 | 久久婷婷色 | 高清av在线免费观看 | 亚洲欧美日韩在线一区二区 | 亚洲精品乱码久久久久v最新版 | 99亚洲精品在线 | 国精产品999国精产品岳 | 麻豆视频在线播放 | 久久国产精品小视频 | 久久久久久久久久久精 | 久久久久久久久毛片精品 | 美女国内精品自产拍在线播放 | 麻豆一区二区三区视频 | 久久91久久久久麻豆精品 | 在线视频 精品 | 视频在线在亚洲 | 欧美成人黄色 | 四虎影视精品 | 丁香视频全集免费观看 | 欧美性生活一级片 | 久久观看最新视频 | 欧美精品久久久久性色 | 欧美黄在线 | 黄色毛片电影 | 欧美一二三四在线 | 午夜国产福利在线观看 | 亚洲视频免费在线观看 | 欧美日韩中文在线观看 | 国产精品91一区 | 日韩免费高清 | 久久久久福利视频 | 久久久久久久久久久福利 | 国产一区免费观看 | 国产成人久久av免费高清密臂 | 在线看片成人 | 成年人免费在线播放 | 天天做天天爱天天爽综合网 | 黄p网站在线观看 | 国产自产在线视频 | 亚洲最大av网站 | 国产一级免费视频 | 精品国产诱惑 | 亚洲精品456在线播放乱码 | 日韩黄色大片在线观看 | 久久超碰网 | 成人在线视频网 | 日本黄色免费大片 | 久久艹久久 | 国产精品视频999 | 久久国产免费视频 | 国产成人一区二区三区在线观看 | 欧美日韩在线播放一区 | 久久久久免费精品国产 | 欧美日韩不卡在线观看 | 国产亚洲一区二区在线观看 | 99精品在线免费观看 | 激情婷婷亚洲 | 婷婷99| 久久国产精品视频 | 天天插天天狠天天透 | 91九色porn在线资源 | 色www.| 99这里只有精品视频 | 中文字幕在线观看一区二区 | 午夜视频99 | 久久九九精品 | 亚洲精品国精品久久99热一 | 亚洲黄色成人网 | 美女免费av | 日本天天操 | 99精品视频在线观看 | 免费毛片一区二区三区久久久 | 午夜精品一区二区三区免费视频 | 久久国产电影 | 免费成人在线网站 | 国产69熟 | 最近中文字幕大全中文字幕免费 | 最近中文字幕 | 夜夜狠狠 | 91高清不卡 | 97精品免费视频 | 国产美女网站在线观看 | 永久av免费在线观看 | 精品国产激情 | 麻豆精品国产传媒 | 欧美激情第一页xxx 午夜性福利 | 免费在线观看视频a | 亚洲精品中文字幕在线 | 亚洲精品一区二区三区在线观看 | 97久久久免费福利网址 | 欧美 亚洲 另类 激情 另类 | www.亚洲精品 | 日韩免费观看一区二区三区 | 日韩a欧美 | 在线观看一区二区视频 | 亚洲欧美va | 亚洲激情p| 久久狠狠一本精品综合网 | 国产亚洲精品久久19p | 一区二区三区不卡在线 | 成人av影视观看 | 国产在线污 | 国产小视频免费在线观看 | 免费亚洲视频在线观看 | a天堂免费 | 亚洲午夜久久久久久久久 | 免费看一及片 | 91大片网站 | 成人免费在线观看电影 | 久精品视频在线观看 | 国产色区 | 成人黄色在线 | 国产人成在线视频 | 丝袜制服综合网 | 日本在线观看一区二区三区 | 久久露脸国产精品 | 精品综合久久 | 精品久久久久久久久久久院品网 | 日韩中文字幕视频在线观看 | 午夜国产一区二区三区四区 | 精品久久久久久久久久岛国gif | 午夜男人影院 | 五月婷婷黄色 | 97超级碰碰 | 韩国视频一区二区三区 | 亚洲一区久久 | 免费在线观看视频a | 天天天操天天天干 | 在线观看国产区 | 91香蕉视频污在线 | 深爱五月激情网 | 欧美在线视频一区二区 | 极品久久久久 | 91高清免费| 中文字幕中文字幕 | 在线免费观看黄色小说 | 国产精品女人久久久 | 正在播放一区 | 成人久久久久 | 午夜在线免费观看视频 | 亚洲高清在线观看视频 | 国产中文字幕视频在线 | 成人av免费| 人人爽人人爽人人 | 精品成人a区在线观看 | 国产精品无 | 99婷婷狠狠成为人免费视频 | 亚洲综合日韩在线 | 日韩在线观看一区 | 天天干天天色2020 | 国产免费黄视频在线观看 | 久久tv| 国产精品亚洲片在线播放 | 国产亚洲情侣一区二区无 | 国产黄网站在线观看 | 四川bbb搡bbb爽爽视频 | 久久久久久网站 | 久久久久久久影视 | 奇米影视777四色米奇影院 | 日韩av线观看| 亚洲91精品 | 色噜噜在线观看视频 | 精品黄色片 | 91看片看淫黄大片 | 免费在线激情视频 | 亚洲精品欧美成人 | 韩国av在线| www久久99 | h动漫中文字幕 | 天天操天天色天天射 | 久久成人亚洲欧美电影 | 狠狠色丁香久久婷婷综合五月 | 欧美日本不卡高清 | 精品九九久久 | 1024久久| 国产精品久久久久久a | 人人澡人人添人人爽一区二区 | 日韩免费不卡av | 国产91对白在线播 | 超碰在线91 | 欧美人交a欧美精品 | 日本视频不卡 | 久久久久久久久久久免费视频 | 天天操天天摸天天射 | 亚洲 欧美日韩 国产 中文 | 国产精品女人久久久 | 中文字幕日韩高清 | 91福利试看 | 国产不卡免费av | 国产精品 久久 | 激情视频在线高清看 | 97视频在线播放 | 99久久精品国 | 91麻豆国产福利在线观看 | 97碰视频| 91视频免费看片 | 日本99热| 9草在线 | 天天草天天草 | 亚洲电影免费 | 国产无遮挡猛进猛出免费软件 | 四虎在线免费 | 国内精品久久久久久久久久清纯 | 国产一区电影在线观看 | 国内成人综合 | 久久精品一区二区国产 | 欧美综合久久久 | 天天舔天天射天天操 | 国产精品一区二区美女视频免费看 | 国产在线免费 | 成人激情开心网 | 五月综合激情网 | 国产精品一区二区果冻传媒 | 亚洲国产成人精品电影在线观看 | 亚洲第一香蕉视频 | 久久伊人免费视频 | av不卡网站 | 91成年人在线观看 | 国产亚洲亚洲 | 国产成人久久精品77777 | 亚洲乱码精品 | 亚洲国产精品成人av | 超碰成人免费电影 | 在线观看成人av | 国产人成看黄久久久久久久久 | 国产淫片免费看 | 久久婷婷五月综合色丁香 | 一区二区三区四区五区在线视频 | 日韩有码中文字幕在线 | 91爱爱网址 | 欧美精品免费视频 | 九九色网| 婷婷国产视频 | 免费观看第二部31集 | av免费观看高清 | 国精产品999国精产 久久久久 | 国产成人精品亚洲日本在线观看 | 蜜桃av观看 | 国产一区二区综合 | 国产不卡网站 | 最新中文在线视频 | 懂色av懂色av粉嫩av分享吧 | 亚洲v精品 | 五月激情丁香婷婷 | av网站免费看 | 日韩在线播放欧美字幕 | 亚洲日本va午夜在线影院 | 91福利国产在线观看 | 国产精品一区二区av | 免费福利片 | 深夜福利视频一区二区 | 亚洲精品视频在 | 国产一级精品视频 | 综合网在线视频 | 爱色婷婷| 中文在线a天堂 | 天天操比 | 日韩av电影中文字幕 | 一二区电影 | 日日夜夜精品免费视频 | 国产专区第一页 | 国产精品久免费的黄网站 | 国产视频中文字幕 | 国产精品18久久久久白浆 | 久久久99精品免费观看 | 日韩三级精品 | www黄色com| 狠狠干美女 | 九九免费在线观看视频 | 国产97视频| 欧美色道 | 国内精品久久久久久久影视简单 | 国产自制av | 深夜精品福利 | 亚洲精品美女在线 | 在线免费观看麻豆 | 一本到在线 | 久久久久久久久网站 | 国产精品久久人 | 中文在线a天堂 | 中文字幕国产 | 免费成人在线网站 | 亚洲精品天天 | 国产精品毛片一区视频 | 97偷拍视频| 国产乱对白刺激视频在线观看女王 | 激情影院在线观看 | 黄色一级大片在线观看 | 成人av免费电影 | 在线国产欧美 | 国产在线理论片 | 国产一区二区在线免费视频 | 五月天av在线 | av一本久道久久波多野结衣 | 久久精品国产亚洲精品2020 | 91视频com| 在线观看一区二区精品 | 黄色亚洲在线 | 四虎永久精品在线 | 91黄色小视频 | 久久99国产精品视频 | 亚洲一区二区精品视频 | free,性欧美| www激情com | 97在线视频免费看 | 日韩www在线| 国产精品99蜜臀久久不卡二区 | 日韩免费不卡av | 九色视频网站 | 免费高清在线视频一区· | 日韩 国产| 四虎影视8848aamm | 成年人天堂com | 欧美一区影院 | 欧美大荫蒂xxx | 中文在线8新资源库 | 在线免费观看亚洲视频 | 天天操天天干天天操天天干 | 日韩中文字幕亚洲一区二区va在线 | 在线观看国产区 | 西西www4444大胆在线 | 伊人婷婷综合 | 色就是色综合 | 婷久久| 国产一区二区精品91 | 日韩精品免费一区二区三区 | 欧美一级片免费播放 | 亚洲1级片 | 99久久精品国产毛片 | 久久精品7 | 91在线播放国产 | 国产精品久久久久久久久久久免费 | 西西444www大胆高清图片 | 精品一区二区久久久久久久网站 | 欧美日韩在线视频免费 | 日本一区二区免费在线观看 | 在线观看精品黄av片免费 | 午夜av在线播放 | 久久久免费观看完整版 | 国产品久精国精产拍 | 国产精品黄色 | 香蕉视频18 | 91视频免费看 | 亚洲永久国产精品 | 午夜婷婷综合 | www.亚洲精品在线 | 国产精品视频区 | 国产成人综合在线观看 | 国产高清在线免费观看 | 99久久精品国产一区二区三区 | 欧美一区二区三区免费看 | av高清网站在线观看 | 久久久久久久亚洲精品 | 午夜av在线电影 | 99久久精品日本一区二区免费 | 成人动漫精品一区二区 | 久久久网站 | 欧美综合在线视频 | 欧美精品久久久久久久 | 欧美在线视频免费 | 久久试看| 亚洲精品久久久久999中文字幕 | 99av国产精品欲麻豆 | 国产精品久久久久久麻豆一区 | 久久免费片 | 中文字幕乱码视频 | 国产中文字幕视频在线 | 97人人澡人人添人人爽超碰 | 亚洲视频在线看 | 久久综合九色综合97婷婷女人 | 亚洲另类在线视频 | 日韩视频一 | 激情网站免费观看 | www国产亚洲精品久久网站 | 五月婷婷天堂 | 亚洲综合在 | 99在线视频免费观看 | www.国产视频 | 成人av在线直播 | 国产999视频在线观看 | 国产在线精品福利 | 在线观看电影av | 精品国产乱码久久久久久浪潮 | 亚洲japanese制服美女 | 四月婷婷在线观看 | 久久免费国产 | 欧美精品一区二区蜜臀亚洲 | 亚洲精品高清一区二区三区四区 | 欧美一级性 | 婷婷免费在线视频 | 久久久久综合精品福利啪啪 | 在线视频 国产 日韩 | av免费看在线 | 日韩免费看片 | 一级欧美黄 | 久久综合中文色婷婷 | 天天插天天狠 | 中文字幕在线观看免费高清电影 | 成年人在线视频观看 | 亚洲精品人人 | 国产专区在线看 | 一级片色播影院 | 中文字幕在线观看网址 | 日日射天天射 | 日韩r级电影在线观看 | 国产91影视 | 99久久99热这里只有精品 | 免费视频 三区 | 在线观看视频97 | 麻豆视频在线观看免费 | 性色av免费看| 蜜桃视频在线观看一区 | 亚欧日韩成人h片 | 国产黑丝一区二区 | 久久在线精品视频 | 国产系列精品av | 日韩免费电影在线观看 | 婷婷六月天丁香 | 国产精品久久久久久久久毛片 | 免费日韩电影 | 天天操天天草 | 蜜臀av性久久久久av蜜臀妖精 | 国产麻豆电影在线观看 | avwww在线观看 | 九九热在线视频 | 日本精品久久久一区二区三区 | 日本公妇在线观看高清 | 午夜精品久久久久久久99热影院 | 91综合在线| 国产精品视频在线观看 | 毛片永久新网址首页 | 色丁香综合 | 亚洲理论在线观看电影 | 日本爱爱免费视频 | 日韩免费视频 | 亚洲一区av | 狠狠操狠狠操 | 成人作爱视频 | 国产视频一区在线免费观看 | 人人藻人人澡人人爽 | 美女性爽视频国产免费app | 丁香婷婷综合网 | 手机看片1042 | 91免费日韩 | 一级片观看 | 一级免费片 | 国色天香第二季 | 人人玩人人添人人澡97 | 久久精品五月 | 在线国产欧美 | 成人在线免费视频观看 | 99视频精品全部免费 在线 | 久久精品国产一区二区三区 | 蜜臀av性久久久久av蜜臀三区 | 一级黄色免费网站 | 中文字幕日韩一区二区三区不卡 | 在线观看精品黄av片免费 | 国产亚洲视频中文字幕视频 | 成人免费观看网站 | 色狠狠久久av五月综合 | 日韩伦理片一区二区三区 | 黄色三级免费片 | 黄色网在线免费观看 | www欧美xxxx| 日韩视频一区二区在线 | 五月婷婷在线观看 | 色中色资源站 | 韩国精品一区二区三区六区色诱 | 久久视频这里有久久精品视频11 | 日韩成人精品 | 六月激情丁香 | 免费日韩 精品中文字幕视频在线 | 成人毛片网 | 欧美一区二区三区不卡 | 免费看国产视频 | 国产精品去看片 | 国产精品久久久久久久毛片 | 久久久久久影视 | 免费人成在线观看网站 | 亚洲精品乱码久久久久久久久久 | 五月综合婷 | 久久爱资源网 | 中文字幕色婷婷在线视频 | 国产精品伦一区二区三区视频 | 日韩免费视频线观看 | 日日躁夜夜躁aaaaxxxx | 国产中年夫妇高潮精品视频 | 天天操天天综合网 | 久久黄视频 | 午夜久久久久久久久久久 | 久草在线高清视频 | 99久久99 | 91丨九色丨丝袜 | 四虎4hu永久免费 | 久久综合狠狠综合久久激情 | 欧美va天堂在线电影 | 亚洲欧美日韩国产精品一区午夜 | 久久av网址 | av在线电影免费观看 | 亚洲国产成人在线播放 | 超碰在线免费福利 | 91香蕉亚洲精品 | 91桃色在线免费观看 | 丁香av在线| 亚洲春色成人 | 在线观看激情av | 国产日本高清 | 国产精品理论片在线播放 | 国产日产精品一区二区三区四区 | 99视频国产精品 | www色片 | 99久久精品国产一区二区三区 | 亚洲精品日韩在线观看 | 麻豆91在线播放 | 久久资源总站 | 一区二区三区观看 | 麻豆一区在线观看 | 日韩电影黄色 | 四虎永久网站 | 国产无吗一区二区三区在线欢 | 久久爱资源网 | 夜夜躁狠狠燥 | 射射色| 亚洲成人精品久久 | 亚洲美女在线一区 | 成人亚洲免费 | 成人免费在线电影 | 中文字幕亚洲精品日韩 | 国产免费精彩视频 | 亚洲精品9 | 韩国精品福利一区二区三区 | 国产精品日韩在线播放 | a天堂中文在线 | 国产成人av电影在线 | 又黄又爽又无遮挡的视频 | 91精品免费看 | 国产亚洲精品电影 | 欧美男女爱爱视频 | 激情网在线观看 | 人人看97 | 久草在线视频免费资源观看 | 96精品在线 | 玖玖视频网 | 久久久久久久久免费 | 最近中文字幕免费大全 | 中文字幕在线观看网站 | 波多野结衣视频一区二区 | 久久久在线免费观看 | 天天色天天综合网 | 在线一区av | 91久久一区二区 | 亚洲精品久久久久久久不卡四虎 | 激情五月在线观看 | 久久久精品国产一区二区电影四季 | 中文在线免费观看 | 欧美日韩免费观看一区=区三区 | 久久专区 | 成人观看 | 欧美精品一区二区蜜臀亚洲 | 亚洲精品日韩一区二区电影 | 日韩精品一区二区在线观看视频 | 日韩一区二区三区不卡 | 日日操操 | 天天干,夜夜操 | 国产一级一级国产 | 精品国产日本 | 少妇自拍av | 久久精品国产精品亚洲精品 | 色综久久 | 国产在线毛片 | www免费看片com| av电影在线不卡 | 丁香综合| 国产99久久 | 狠狠色狠狠色综合系列 | 97成人精品视频在线播放 | 在线观看成人国产 | 午夜av网站 | 日韩一级电影在线观看 | 91精品黄色 | 美女网站视频久久 | 久久99精品国产麻豆婷婷 | 成人动漫一区二区三区 | 亚洲第一中文字幕 | 国产精品成人一区二区 | 国产精品久久久久影院 | 91看片麻豆| 香蕉手机在线 | 波多野结衣一区二区 | 中文超碰字幕 | 欧美午夜性 | 国产高清精 | 亚洲三级在线播放 | 日韩有码专区 | 国产精品午夜免费福利视频 | 国产精品美女久久久久aⅴ 干干夜夜 | 特级黄色视频毛片 | 亚洲1区 在线 | 精品亚洲免a | av大片免费在线观看 | 岛国精品一区二区 | 色综合久久99 | 日韩精品高清不卡 | 国产三级视频在线 | 999久久久免费视频 午夜国产在线观看 | 久久久久久久久久久电影 | 日本精品免费看 | 成人av动漫在线 | 亚洲精品www久久久久久 | 日韩字幕在线 | 在线视频1卡二卡三卡 | 国产中文字幕在线免费观看 | 色视频在线免费观看 | 成人avav| 夜夜躁狠狠躁 | 久久久久久久久久久福利 | 91高清免费 | 在线免费观看国产视频 | 国产999精品久久久久久 | 国产精品亚洲片夜色在线 | 日韩欧美一区二区三区在线 | 欧美日韩在线免费视频 | 成人久久18免费 | 国产精品尤物视频 | 中文字幕在线观看一区 | 欧美一区二视频在线免费观看 | 在线观看成年人 | 色多多在线观看 | 国产精品视频在线看 | 午夜影视剧场 | 日韩免费观看视频 | 亚州天堂 | 黄色福利网站 | 狠狠干夜夜爱 | 韩日三级在线 | 黄色a在线观看 | 亚洲在线资源 | 韩国在线一区二区 | 超碰在线最新网址 | 欧美一区二区日韩一区二区 | 免费视频97 | 亚在线播放中文视频 | 蜜桃视频成人在线观看 | 日韩黄色一区 | 婷婷五月色综合 | av一区二区在线观看中文字幕 | 91.dizhi永久地址最新 | www.99热精品 | 久久久久久久久久影视 | 特级西西444www大胆高清无视频 | 国内精品久久久久影院一蜜桃 | 国产一区二区播放 | 成人91免费视频 | 中文视频一区二区 | 一区二区三区四区五区在线视频 | 久久综合射 | 国产精品久久久久久久久蜜臀 | 久久婷婷五月综合色丁香 | 涩涩资源网 | 黄色小说视频网站 | 97国产精品亚洲精品 | 超碰在线人人草 | 国产特级毛片aaaaaaa高清 | 日韩色高清 | 亚洲黄色一级大片 | 91精品国产高清自在线观看 | 欧美做受69 | 久久婷婷色| 中文av一区二区 | 国内精品亚洲 | 色视频网站免费观看 | 国产黄色免费 | 激情五月看片 | 国产精品一区二区你懂的 | 日韩艹| 国产一区二区三区在线免费观看 | 操操碰| 在线观看第一页 | 亚洲精品a区 | 色天堂在线视频 | 亚洲国产中文字幕在线观看 | 欧美激情综合网 | 成人av电影免费在线播放 | 亚洲电影影音先锋 | 天天操天天吃 | 久久婷婷影视 | 97人人澡人人添人人爽超碰 | 亚洲成人av电影在线 | 国产精品丝袜久久久久久久不卡 | 在线观看蜜桃视频 | 精品国产aⅴ麻豆 | a成人v | 亚洲综合丁香 | 中文字字幕在线 | 中文字幕乱在线伦视频中文字幕乱码在线 | 国产在线观看91 | 日韩在线观看一区二区三区 | 久久综合偷偷噜噜噜色 | 五月激情天 | 在线 欧美 日韩 | 国产精品资源在线 | 日韩三区在线观看 | 国产精品一区二区av | 国产精品久久久久久久久久东京 | av综合站| 九九九在线观看 | 色婷在线 | 黄p在线播放 | 黄色官网在线观看 | 伊人婷婷 | 国产精品久久久久久久久搜平片 | 高清不卡免费视频 | 日韩网站在线看片你懂的 | 精品在线观看国产 | 麻豆国产精品永久免费视频 | 色五月色开心色婷婷色丁香 | 日日夜夜天天人人 | 久久久香蕉视频 | 日本久久精 | 狠狠躁日日躁狂躁夜夜躁av | 日韩网站视频 | 国产高清一区二区 | 国产精品福利小视频 | 人人看看人人 | 欧美国产高清 | 国产免费观看av | 99久久er热在这里只有精品15 | 五月婷视频| 99热在线这里只有精品 | 五月色综合 | 国产女教师精品久久av | 亚洲国产日韩在线 | 91麻豆国产 | 久久精品这里热有精品 | 日韩精品免费在线观看 | 99久久精品国产亚洲 | 亚洲精品乱码久久久久v最新版 | 91系列在线 | 欧美精品色 | 玖玖玖影院 | 亚洲精品视频在线观看网站 | 91麻豆看国产在线紧急地址 | 久久影视一区 | 欧美一级爽 | 中文字幕专区高清在线观看 | 在线不卡视频 | 五月婷在线播放 | 在线黄色av| 日韩欧美xxxx | 国产成人精品一区二区三区网站观看 | 黄色a在线观看 | 黄色av网站在线观看 | 亚洲精品系列 | 九色91福利 | 三级小视频在线观看 | 中文字幕久久网 | av不卡网站 | 国产精品自产拍在线观看蜜 | 亚洲区另类春色综合小说 | h文在线观看免费 | 日韩理论在线播放 | 夜夜干天天操 | 国产96在线 | 97超碰在线久草超碰在线观看 | 精品国产1区二区 | 精品嫩模福利一区二区蜜臀 | 久久精品国产精品亚洲精品 | 日韩xxx视频| 亚洲视频在线免费观看 | 国产精品99久久久久人中文网介绍 | 一区 二区 精品 | 国产成人在线一区 | 日韩av快播电影网 | 四虎影视成人永久免费观看亚洲欧美 | 精品免费| 黄色片免费在线 | 久久天天躁夜夜躁狠狠85麻豆 | 日韩成人邪恶影片 | 免费观看一级视频 | 97精品国产97久久久久久 | 高清不卡一区二区在线 | 久久久久www| 久久久久女教师免费一区 | 国产尤物一区二区三区 | 午夜精品久久久99热福利 | 成人av网页 | 蜜桃视频成人在线观看 | 欧洲成人av| 99热这里是精品 | 国产高清小视频 | av中文字幕免费在线观看 | 日韩成人免费在线观看 | 一区二区视频在线播放 | www.色婷婷.com | 婷婷丁香花 | 国产午夜精品视频 | av中文天堂 | 不卡av在线免费观看 | 久久精品艹 | 99久久久久 | 人人玩人人添人人澡超碰 | 狠狠色噜噜狠狠狠狠2022 | 亚洲精品视频在线看 | 国产手机在线 | 2023年中文无字幕文字 | 色综合久久精品 | 狠狠的干狠狠的操 | 日韩三级在线观看 | 国产精品av免费在线观看 | 国产精品永久 | 日日夜夜天天综合 | 日本精品视频网站 | 欧美aa级| 国产第一页在线观看 | 欧美巨大| 国产精品 国内视频 | 久久丁香网| 日本aaaa级毛片在线看 | 久草在线资源网 | 久久国产二区 | 久草在线资源视频 | 成人在线视频免费观看 | 国产精品久久久久久久午夜片 | 成人 亚洲 欧美 | 日本中文字幕在线免费观看 | 91.精品高清在线观看 | 国产亚洲视频中文字幕视频 | 精品久久久网 | 在线电影中文字幕 | 亚洲精品videossex少妇 | 国产精品精 | 色五月激情五月 | 69av免费视频 | 一级免费看 | 最新久久免费视频 | 91资源在线免费观看 | 精品自拍sae8—视频 | 国产资源在线观看 | 国产精品毛片一区 | 国产一级二级三级视频 | 国产白浆视频 | 国内精品久久久久久久久久 | 69久久夜色精品国产69 | 91精品在线播放 | 欧洲精品久久久久毛片完整版 | 日韩精品视频一二三 | 免费网址在线播放 | 啪啪凸凸 | 8x成人免费视频 | 人人艹人人 | 国产精品久久久久久电影 | 观看免费av | 一区二区不卡高清 | 干亚洲少妇 | www99精品| av色一区| 西西人体4444www高清视频 | 精品国产一区二区三区四区在线观看 | 免费网址你懂的 | 一区二区 不卡 | 一区二区视| 美女国产| 成人av一级片 | 欧美色噜噜噜 | 久久69av | 久久综合九色综合欧美狠狠 | 国产成人福利在线观看 | av观看网站 | 婷婷色网站| 国产123区在线观看 国产精品麻豆91 | 91夫妻视频 | 一区二区视频在线观看免费 | 嫩草伊人久久精品少妇av | 色网av| 久热免费 | 日韩黄色免费在线观看 | 久久精品美女视频 | 国产精品一区二区电影 | 日韩a级免费视频 | 午夜av一区| 欧美一进一出抽搐大尺度视频 | 日韩69av | 99久久www| 美女黄频在线观看 | 在线免费av电影 | 国产精品成人国产乱一区 | 精品字幕 | 激情五月婷婷综合网 | 日韩成人精品 | 国产一区二区高清视频 | 91人人澡人人爽 | 又黄又爽免费视频 | 国产精品短视频 | 成年人网站免费观看 | 中文字幕在线观看第二页 | 精品国产资源 | 欧美精品久久久久久久亚洲调教 | 亚洲精品午夜久久久久久久久久久 | 在线观看中文字幕网站 | 最近中文字幕完整高清 | 美女免费视频黄 | 久久久亚洲精品 |