日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問(wèn)題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷解決方案
Android進(jìn)階:深入理解Android窗口管理框架機(jī)制

[[423965]]

前言

WindowManagerService是位于Framework層的窗口管理服務(wù),它的職責(zé)是管理系統(tǒng)中的所有窗口,也就是Window,關(guān)于Window的介紹,通俗來(lái)說(shuō),Window就是手機(jī)上一塊顯示區(qū)域,也就是Android中的繪制畫布Surface,添加一個(gè)Window的過(guò)程,也就是申請(qǐng)分配一塊Surface的過(guò)程,而整個(gè)流程的管理者正是WindowManagerService;

創(chuàng)新互聯(lián)建站專注于企業(yè)全網(wǎng)營(yíng)銷推廣、網(wǎng)站重做改版、伊犁網(wǎng)站定制設(shè)計(jì)、自適應(yīng)品牌網(wǎng)站建設(shè)、H5場(chǎng)景定制、商城系統(tǒng)網(wǎng)站開(kāi)發(fā)、集團(tuán)公司官網(wǎng)建設(shè)、外貿(mào)網(wǎng)站建設(shè)、高端網(wǎng)站制作、響應(yīng)式網(wǎng)頁(yè)設(shè)計(jì)等建站業(yè)務(wù),價(jià)格優(yōu)惠性價(jià)比高,為伊犁等各大城市提供網(wǎng)站開(kāi)發(fā)制作服務(wù)。

今天我們來(lái)分析下窗口WMS相關(guān)的知識(shí)點(diǎn);

一、窗口相關(guān)概念

1、WindowManagerService概念

(1)WindowManagerService概念

Framework層的窗口管理服務(wù),職責(zé)是管理Android系統(tǒng)中所有window。窗口管理服務(wù),繼承IWindowManager.Stub,Binder服務(wù)端,因此WM與WMS的交互也是一個(gè)IPC過(guò)程。WMS主要做的事情如下:

  • Z-ordered的維護(hù)函數(shù)
  • 輸入法管理
  • AddWindow/RemoveWindow
  • Layerout
  • Token管理,AppToken
  • 活動(dòng)窗口管理(FocusWindow)
  • 活動(dòng)應(yīng)用管理(FocusApp)
  • 轉(zhuǎn)場(chǎng)動(dòng)畫
  • 系統(tǒng)消息收集線程
  • 系統(tǒng)消息分發(fā)線程

(2)WindowManager

應(yīng)用與窗口管理服務(wù)WindowManagerService交互的接口;

(3)PhoneWindowManager

實(shí)現(xiàn)了窗口的各種策略,定義了窗口相關(guān)策略,比如:告訴WMS某一個(gè)類型Window的Z-Order的值是多少,幫助WMS矯正不合理的窗口屬性,為WMS監(jiān)聽(tīng)屏幕旋轉(zhuǎn)的狀態(tài),預(yù)處理一些系統(tǒng)按鍵事件;

(4)Choreographer

用戶控制窗口動(dòng)畫、屏幕選擇等操作,它擁有從顯示子系統(tǒng)獲取Vsync同步事件的能力,從而可以在合適的時(shí)機(jī)通知渲染動(dòng)作,避免在渲染的過(guò)程中因?yàn)榘l(fā)生屏幕重繪而導(dǎo)致的畫面撕裂。WMS使用Choreographer負(fù)責(zé)驅(qū)動(dòng)所有的窗口動(dòng)畫、屏幕旋轉(zhuǎn)動(dòng)畫、墻紙動(dòng)畫的渲染;

(5)DisplayContent

用于描述多屏輸出相關(guān)信息;

根據(jù)窗口的顯示位置將其分組。隸屬于同一個(gè)DisplayContent的窗口將會(huì)被顯示在同一個(gè)屏幕中。每個(gè)DisplayContent都對(duì)應(yīng)著唯一ID,在添加窗口的時(shí)候可以通過(guò)指定這個(gè)ID決定其將顯示在哪個(gè)屏幕中;

DisplayContent是一個(gè)非常具有隔離性的一個(gè)概念。處于不同DisplayContent的兩個(gè)窗口在布局、顯示順序以及動(dòng)畫處理上不會(huì)產(chǎn)生任何耦合;

(6)WindowState

描述窗口的狀態(tài)信息以及和WindowManagerService進(jìn)行通信,一般一個(gè)窗口對(duì)應(yīng)一個(gè)WindowState。它用來(lái)表示一個(gè)窗口的所有屬性;

(7)WindowToken

  • 窗口Token,用來(lái)做Binder通信;同時(shí)也是一種標(biāo)識(shí);
  • 在進(jìn)行窗口Zorder排序時(shí),屬于同一個(gè)WindowToken的窗口會(huì)被安排在一起,而且在其中定義的一些屬性將會(huì)影響所有屬于此WindowToken的窗口,這些都表明了屬于同一個(gè)WindowToken的窗口之間的緊密聯(lián)系;
  • 應(yīng)用組件在需要新的窗口時(shí),必須提供WindowToken以表明自己的身份,并且窗口的類型必須與所持有的WindowToken的類型一致;
  • 在創(chuàng)建系統(tǒng)類型的窗口時(shí)不需要提供一個(gè)有效的Token,WMS會(huì)隱式地為其聲明一個(gè)WindowToken,看起來(lái)誰(shuí)都可以添加個(gè)系統(tǒng)級(jí)的窗口。難道Android為了內(nèi)部使用方便而置安全于不顧嗎?非也,addWindow()函數(shù)一開(kāi)始的mPolicy.checkAddPermission()的目的就是如此。它要求客戶端必須擁有SYSTEM_ALERT_WINDOW或INTERNAL_SYSTEM_WINDOW權(quán)限才能創(chuàng)建系;

(8)Session

App進(jìn)程通過(guò)建立Session代理對(duì)象和Session對(duì)象通信,進(jìn)而和WMS建立連接;

(9)SurfaceFlinger

SurfaceFlinger負(fù)責(zé)管理Android系統(tǒng)的幀緩沖區(qū)(Frame Buffer),Android設(shè)備的顯示屏被抽象為一個(gè)幀緩沖區(qū),而Android系統(tǒng)中的SurfaceFlinger服務(wù)就是通過(guò)向這個(gè)幀緩沖區(qū)寫入內(nèi)容來(lái)繪制應(yīng)用程序中的用戶界面的;

(10)InputManager

管理每個(gè)窗口的輸入事件通道(InputChannel)以及向通道上派發(fā)事件;

(11)Animator

所有窗口動(dòng)畫的總管(WindowStateAnimator對(duì)象)。在Choreographer的驅(qū)動(dòng)下,逐個(gè)渲染所有的動(dòng)畫;

2、Window

  • 表示一個(gè)窗口的概念,是所有View的直接管理者,任何視圖都通過(guò)Window呈現(xiàn)(點(diǎn)擊事件由Window->DecorView->View;Activity的setContentView底層通過(guò)Window完成)
  • Window是一個(gè)抽象類,具體實(shí)現(xiàn)是PhoneWindow;
  • 創(chuàng)建Window需要通過(guò)WindowManager創(chuàng)建;
  • WindowManager是外界訪問(wèn)Window的入口;
  • Window的具體實(shí)現(xiàn)位于WindowManagerService中;
  • WindowManager和WindowManagerService的交互是通過(guò)IPC進(jìn)程間通信完成的;
  • 定義窗口樣式和行為的抽象基類,用于作為頂層的View加到WindowManager中,其實(shí)現(xiàn)類是PhoneWindow;
  • 每個(gè)Window都需要指定一個(gè)Type(應(yīng)用窗口、子窗口、系統(tǒng)窗口)。Activity對(duì)應(yīng)的窗口是應(yīng)用窗口;PhoneWindow,ContextMenu,OptionMenu是常用的子窗口;像Toast和系統(tǒng)警告提示框(如ANR)就是系統(tǒng)窗口,還有很多應(yīng)用的懸浮窗也屬于系統(tǒng)窗口;

3、Surface

  • 在Android中,一個(gè)窗口會(huì)獨(dú)占一個(gè)Surface,Surface其實(shí)就是一個(gè)畫布,應(yīng)用程序通過(guò)Canvas或者OpenGL在Surface上繪制內(nèi)容;
  • 在Surface上繪制后,通過(guò)SurfaceFlinger將多塊Surface的內(nèi)容按照Z(yǔ)-order進(jìn)行混合并輸出到FrameBuffer,從而將Android頁(yè)面展示給用戶;
  • 每個(gè)窗口都有一塊Surface用于顯示自己的ui,必然需要一個(gè)角色對(duì)窗口進(jìn)行統(tǒng)一管理,這個(gè)時(shí)候,WMS應(yīng)運(yùn)而生。WMS為所有窗口分配Surface,掌管z-order以及位置、尺寸、窗口的進(jìn)場(chǎng)出場(chǎng)動(dòng)畫,并且還是輸入系統(tǒng)的中轉(zhuǎn)站;
  • 布局系統(tǒng):計(jì)算管理窗口的位置和層次;
  • 動(dòng)畫系統(tǒng):根據(jù)布局系統(tǒng)的計(jì)算渲染窗口動(dòng)畫;

4、Window的Type

  • 應(yīng)用窗口:層級(jí)范圍是1~99
  • 子窗口:層級(jí)范圍是1000~1999
  • 系統(tǒng)窗口:層級(jí)范圍是2000~2999

5、窗口flags顯示屬性

 
 
 
 
  1. // 窗口特征標(biāo)記 
  2. public int flags; 
  3. // 當(dāng)該window對(duì)用戶可見(jiàn)時(shí),允許鎖屏 
  4. public static final int FLAG_ALLOW_LOCK_WHILE_SCREEN_ON     = 0x00000001; 
  5. // 窗口后面的所有內(nèi)容都變暗 
  6. public static final int FLAG_DIM_BEHIND        = 0x00000002; 
  7. // 窗口后面的所有內(nèi)容都變模糊 
  8. public static final int FLAG_BLUR_BEHIND        = 0x00000004; 
  9. // 窗口不能獲得焦點(diǎn) 
  10. public static final int FLAG_NOT_FOCUSABLE      = 0x00000008; 
  11. // 窗口不接受觸摸屏事件 
  12. public static final int FLAG_NOT_TOUCHABLE      = 0x00000010; 
  13. // 即使在該window可獲得焦點(diǎn)情況下,允許該窗口之處的點(diǎn)擊事件傳遞到當(dāng)前窗口后面的窗口去 
  14. public static final int FLAG_NOT_TOUCH_MODAL    = 0x00000020; 
  15. // 當(dāng)手機(jī)處于睡眠狀態(tài),如果屏幕被按下,那么該window將第一個(gè)收到觸摸事件 
  16. public static final int FLAG_TOUCHABLE_WHEN_WAKING = 0x00000040; 
  17. // 當(dāng)該window對(duì)用戶可見(jiàn)時(shí),屏幕處于常亮狀態(tài) 
  18. public static final int FLAG_KEEP_SCREEN_ON     = 0x00000080; 
  19. // 讓window占滿整個(gè)屏幕,不留任何邊界 
  20. public static final int FLAG_LAYOUT_IN_SCREEN   = 0x00000100; 
  21. // 允許窗口超出整個(gè)手機(jī)屏幕 
  22. public static final int FLAG_LAYOUT_NO_LIMITS   = 0x00000200; 
  23. // window全名顯示 
  24. public static final int FLAG_FULLSCREEN      = 0x00000400; 
  25. // 恢復(fù)window非全屏顯示 
  26. public static final int FLAG_FORCE_NOT_FULLSCREEN   = 0x00000800; 
  27. // 開(kāi)啟窗口抖動(dòng) 
  28. public static final int FLAG_DITHER             = 0x00001000; 
  29. // 安全內(nèi)容窗口,該窗口顯示時(shí)不允許截屏 
  30. public static final int FLAG_SECURE             = 0x00002000; 
  31. // 一種特殊模式,在該模式下,布局參數(shù)用于在將表面合成到屏幕時(shí)執(zhí)行縮放。 
  32. public static final int FLAG_SCALED             = 0x00004000; 
  33. public static final int FLAG_IGNORE_CHEEK_PRESSES    = 0x00008000; 
  34. public static final int FLAG_LAYOUT_INSET_DECOR = 0x00010000; 
  35. public static final int FLAG_ALT_FOCUSABLE_IM = 0x00020000; 
  36. // 接收單個(gè)特殊的MotionEvent,以應(yīng)對(duì)窗口外發(fā)生的觸摸。  
  37. // 不會(huì)收到完整的向下/向上/向上手勢(shì),而只會(huì)收到第一次向下的位置作為ACTION_OUTSIDE。 
  38. public static final int FLAG_WATCH_OUTSIDE_TOUCH = 0x00040000; 
  39. // 鎖屏?xí)r顯示該窗口 
  40. public static final int FLAG_SHOW_WHEN_LOCKED = 0x00080000; 
  41. // 系統(tǒng)的墻紙顯示在該窗口之后 
  42. public static final int FLAG_SHOW_WALLPAPER = 0x00100000; 
  43. // 當(dāng)window被顯示的時(shí)候,系統(tǒng)將把它當(dāng)做一個(gè)用戶活動(dòng)事件,以點(diǎn)亮手機(jī)屏幕 
  44. public static final int FLAG_TURN_SCREEN_ON = 0x00200000; 
  45. // 該窗口顯示,消失鍵盤 
  46. public static final int FLAG_DISMISS_KEYGUARD = 0x00400000; 
  47. // 當(dāng)window在可以接受觸摸屏情況下,讓因在該window之外,而發(fā)送到后面的window的 
  48. // 觸摸屏可以支持split touch 
  49. public static final int FLAG_SPLIT_TOUCH = 0x00800000; 
  50. // 對(duì)該window進(jìn)行硬件加速,該flag必須在activity或者dialog的content view之前進(jìn)行設(shè)置 
  51. public static final int FLAG_HARDWARE_ACCELERATED = 0x01000000; 
  52. // 讓該window占滿整個(gè)手機(jī)屏幕,不留任何邊界 
  53. public static final int FLAG_LAYOUT_IN_OVERSCAN = 0x02000000; 
  54. // 透明狀態(tài)欄 
  55. public static final int FLAG_TRANSLUCENT_STATUS = 0x04000000; 
  56. // 透明導(dǎo)航欄 
  57. public static final int FLAG_TRANSLUCENT_STATUS = 0x04000000; 

二、 Window的添加流程

 
 
 
 
  1. public final class WindowManagerGlobal { 
  2.      public void addView(View view, ViewGroup.LayoutParams params, 
  3.                 Display display, Window parentWindow) { 
  4.             //校驗(yàn)參數(shù)的合法性 
  5.             ... 
  6.             //ViewRootImpl封裝了View與WindowManager的交互力促 
  7.             ViewRootImpl root; 
  8.             View panelParentView = null; 
  9.             synchronized (mLock) { 
  10.                 // Start watching for system property changes. 
  11.                 if (mSystemPropertyUpdater == null) { 
  12.                     mSystemPropertyUpdater = new Runnable() { 
  13.                         @Override public void run() { 
  14.                             synchronized (mLock) { 
  15.                                 for (int i = mRoots.size() - 1; i >= 0; --i) { 
  16.                                     mRoots.get(i).loadSystemProperties(); 
  17.                                 } 
  18.                             } 
  19.                         } 
  20.                     }; 
  21.                     SystemProperties.addChangeCallback(mSystemPropertyUpdater); 
  22.                 } 
  23.                 int index = findViewLocked(view, false); 
  24.                 if (index >= 0) { 
  25.                     if (mDyingViews.contains(view)) { 
  26.                         // Don't wait for MSG_DIE to make it's way through root's queue. 
  27.                         mRoots.get(index).doDie(); 
  28.                     } else { 
  29.                         throw new IllegalStateException("View " + view 
  30.                                 + " has already been added to the window manager."); 
  31.                     } 
  32.                     // The previous removeView() had not completed executing. Now it has. 
  33.                 } 
  34.                 // If this is a panel window, then find the window it is being 
  35.                 // attached to for future reference. 
  36.                 if (wparams.type >= WindowManager.LayoutParams.FIRST_SUB_WINDOW && 
  37.                         wparams.type <= WindowManager.LayoutParams.LAST_SUB_WINDOW) { 
  38.                     final int count = mViews.size(); 
  39.                     for (int i = 0; i < count; i++) { 
  40.                         if (mRoots.get(i).mWindow.asBinder() == wparams.token) { 
  41.                             panelParentView = mViews.get(i); 
  42.                         } 
  43.                     } 
  44.                 } 
  45.                 //通過(guò)上下文構(gòu)建ViewRootImpl 
  46.                 root = new ViewRootImpl(view.getContext(), display); 
  47.                 view.setLayoutParams(wparams); 
  48.                 //mViews存儲(chǔ)著所有Window對(duì)應(yīng)的View對(duì)象 
  49.                 mViews.add(view); 
  50.                 //mRoots存儲(chǔ)著所有Window對(duì)應(yīng)的ViewRootImpl對(duì)象 
  51.                 mRoots.add(root); 
  52.                 //mParams存儲(chǔ)著所有Window對(duì)應(yīng)的WindowManager.LayoutParams對(duì)象 
  53.                 mParams.add(wparams); 
  54.             } 
  55.             // do this last because it fires off messages to start doing things 
  56.             try { 
  57.                 //調(diào)用ViewRootImpl.setView()方法完成Window的添加并更新界面 
  58.                 root.setView(view, wparams, panelParentView); 
  59.             } catch (RuntimeException e) { 
  60.                 // BadTokenException or InvalidDisplayException, clean up. 
  61.                 synchronized (mLock) { 
  62.                     final int index = findViewLocked(view, false); 
  63.                     if (index >= 0) { 
  64.                         removeViewLocked(index, true); 
  65.                     } 
  66.                 } 
  67.                 throw e; 
  68.             } 
  69.         } 

在這個(gè)方法里有三個(gè)重要的成員變量:

  • mViews 存儲(chǔ)著所有Window對(duì)應(yīng)的View對(duì)象;
  • mRoots 存儲(chǔ)著所有Window對(duì)應(yīng)的ViewRootImpl對(duì)象;
  • mParams 存儲(chǔ)著所有Window對(duì)應(yīng)的WindowManager.LayoutParams對(duì)象;
  • 這里面提到了一個(gè)我們不是很熟悉的類ViewRootImpl,它其實(shí)就是一個(gè)封裝類,封裝了View與WindowManager的交互方式,它是View與WindowManagerService通信的橋梁;
  • 最后也是調(diào)用ViewRootImpl.setView()方法完成Window的添加并更新界面;

我們來(lái)看看這個(gè)方法的實(shí)現(xiàn)

 
 
 
 
  1. public final class ViewRootImpl implements ViewParent, 
  2.         View.AttachInfo.Callbacks, ThreadedRenderer.HardwareDrawCallbacks { 
  3.      public void setView(View view, WindowManager.LayoutParams attrs, View panelParentView) { 
  4.             synchronized (this) { 
  5.                 if (mView == null) { 
  6.                     mView = view; 
  7.                     //參數(shù)校驗(yàn)與預(yù)處理 
  8.                     ... 
  9.                     // Schedule the first layout -before- adding to the window 
  10.                     // manager, to make sure we do the relayout before receiving 
  11.                     // any other events from the system. 
  12.                     //1. 調(diào)用requestLayout()完成界面異步繪制的請(qǐng)求 
  13.                     requestLayout(); 
  14.                     if ((mWindowAttributes.inputFeatures 
  15.                             & WindowManager.LayoutParams.INPUT_FEATURE_NO_INPUT_CHANNEL) == 0) { 
  16.                         mInputChannel = new InputChannel(); 
  17.                     } 
  18.                     mForceDecorViewVisibility = (mWindowAttributes.privateFlags 
  19.                             & PRIVATE_FLAG_FORCE_DECOR_VIEW_VISIBILITY) != 0; 
  20.                     try { 
  21.                         mOrigWindowType = mWindowAttributes.type; 
  22.                         mAttachInfo.mRecomputeGlobalAttributes = true; 
  23.                         collectViewAttributes(); 
  24.                         //2. 創(chuàng)建WindowSession并通過(guò)WindowSession請(qǐng)求WindowManagerService來(lái)完成Window添加的過(guò)程 
  25.                         //這是一個(gè)IPC的過(guò)程。 
  26.                         res = mWindowSession.addToDisplay(mWindow, mSeq, mWindowAttributes, 
  27.                                 getHostVisibility(), mDisplay.getDisplayId(), 
  28.                                 mAttachInfo.mContentInsets, mAttachInfo.mStableInsets, 
  29.                                 mAttachInfo.mOutsets, mInputChannel); 
  30.                     } catch (RemoteException e) { 
  31.                         mAdded = false; 
  32.                         mView = null; 
  33.                         mAttachInfo.mRootView = null; 
  34.                         mInputChannel = null; 
  35.                         mFallbackEventHandler.setView(null); 
  36.                         unscheduleTraversals(); 
  37.                         setAccessibilityFocus(null, null); 
  38.                         throw new RuntimeException("Adding window failed", e); 
  39.                     } finally { 
  40.                         if (restore) { 
  41.                             attrs.restore(); 
  42.                         } 
  43.                     } 
  44.                     ... 
  45.             } 
  46.         }     
  • 調(diào)用requestLayout()完成界面異步繪制的請(qǐng)求,requestLayout()會(huì)去調(diào)用scheduleTraversals()來(lái)完成View的繪制,scheduleTraversals()方法將一個(gè)TraversalRunnable提交到工作隊(duì)列中執(zhí)行View的繪制。而TraversalRunnable最終調(diào)用了performTraversals()方法來(lái)完成實(shí)際的繪制操作。提到performTraversals()方法我們已經(jīng)很熟悉了;
  • 創(chuàng)建WindowSession并通過(guò)WindowSession請(qǐng)求WindowManagerService來(lái)完成Window添加的過(guò)程這是一個(gè)IPC的過(guò)程,WindowManagerService作為實(shí)際的窗口管理者,窗口的創(chuàng)建、刪除和更新都是由它來(lái)完成的,它同時(shí)還負(fù)責(zé)了窗口的層疊排序和大小計(jì)算等工作;

performTraversals()方法的實(shí)現(xiàn):

  • 獲取Surface對(duì)象,用于圖形繪制;
  • 調(diào)用performMeasure()方法測(cè)量視圖樹(shù)各個(gè)View的大小;
  • 調(diào)用performLayout()方法計(jì)算視圖樹(shù)各個(gè)View的位置,進(jìn)行布局;
  • 調(diào)用performMeasure()方法對(duì)視圖樹(shù)的各個(gè)View進(jìn)行繪制;

WindowManager與WindowManagerService的跨進(jìn)程通信。Android的各種服務(wù)都是基于C/S結(jié)構(gòu)來(lái)設(shè)計(jì)的,系統(tǒng)層提供服務(wù),應(yīng)用層使用服務(wù)。WindowManager也是一樣,它與

WindowManagerService的通信是通過(guò)WindowSession來(lái)完成的;

首先調(diào)用ServiceManager.getService("window")獲取WindowManagerService,該方法返回的是IBinder對(duì)象,然后調(diào)用IWindowManager.Stub.asInterface()方法將WindowManagerService轉(zhuǎn)換為一個(gè)IWindowManager對(duì)象;

然后調(diào)用openSession()方法與WindowManagerService建立一個(gè)通信會(huì)話,方便后續(xù)的跨進(jìn)程通信。這個(gè)通信會(huì)話就是后面我們用到的WindowSession;

基本上所有的Android系統(tǒng)服務(wù)都是基于這種方式實(shí)現(xiàn)的,它是一種基于AIDL實(shí)現(xiàn)的IPC的過(guò)程;

 
 
 
 
  1. public final class WindowManagerGlobal { 
  2.     public static IWindowSession getWindowSession() { 
  3.         synchronized (WindowManagerGlobal.class) { 
  4.             if (sWindowSession == null) { 
  5.                 try { 
  6.                     InputMethodManager imm = InputMethodManager.getInstance(); 
  7.                     //獲取WindowManagerService對(duì)象,并將它轉(zhuǎn)換為IWindowManager類型 
  8.                     IWindowManager windowManager = getWindowManagerService(); 
  9.                     //調(diào)用openSession()方法與WindowManagerService建立一個(gè)通信會(huì)話,方便后續(xù)的 
  10.                     //跨進(jìn)程通信。 
  11.                     sWindowSession = windowManager.openSession( 
  12.                             new IWindowSessionCallback.Stub() { 
  13.                                 @Override 
  14.                                 public void onAnimatorScaleChanged(float scale) { 
  15.                                     ValueAnimator.setDurationScale(scale); 
  16.                                 } 
  17.                             }, 
  18.                             imm.getClient(), imm.getInputContext()); 
  19.                 } catch (RemoteException e) { 
  20.                     throw e.rethrowFromSystemServer(); 
  21.                 } 
  22.             } 
  23.             return sWindowSession; 
  24.         } 
  25.     } 
  26.     public static IWindowManager getWindowManagerService() { 
  27.         synchronized (WindowManagerGlobal.class) { 
  28.             if (sWindowManagerService == null) { 
  29.                 //調(diào)用ServiceManager.getService("window")獲取WindowManagerService,該方法返回的是IBinder對(duì)象 
  30.                 //,然后調(diào)用IWindowManager.Stub.asInterface()方法將WindowManagerService轉(zhuǎn)換為一個(gè)IWindowManager對(duì)象 
  31.                 sWindowManagerService = IWindowManager.Stub.asInterface( 
  32.                         ServiceManager.getService("window")); 
  33.                 try { 
  34.                     if (sWindowManagerService != null) { 
  35.                         ValueAnimator.setDurationScale(sWindowManagerService.getCurrentAnimatorScale()); 
  36.                     } 
  37.                 } catch (RemoteException e) { 
  38.                     throw e.rethrowFromSystemServer(); 
  39.                 } 
  40.             } 
  41.             return sWindowManagerService; 
  42.         } 
  43.     } 
  44.  } 

三、 Window的刪除流程

Window的刪除流程也是在WindowManagerGlobal里完成

 
 
 
 
  1. public final class WindowManagerGlobal { 
  2.    public void removeView(View view, boolean immediate) { 
  3.         if (view == null) { 
  4.             throw new IllegalArgumentException("view must not be null"); 
  5.         } 
  6.         synchronized (mLock) { 
  7.             //1. 查找待刪除View的索引 
  8.             int index = findViewLocked(view, true); 
  9.             View curView = mRoots.get(index).getView(); 
  10.             //2. 調(diào)用removeViewLocked()完成View的刪除, removeViewLocked()方法 
  11.             //繼續(xù)調(diào)用ViewRootImpl.die()方法來(lái)完成View的刪除。 
  12.             removeViewLocked(index, immediate); 
  13.             if (curView == view) { 
  14.                 return; 
  15.             } 
  16.             throw new IllegalStateException("Calling with view " + view 
  17.                     + " but the ViewAncestor is attached to " + curView); 
  18.         } 
  19.     } 
  20.     private void removeViewLocked(int index, boolean immediate) { 
  21.         ViewRootImpl root = mRoots.get(index); 
  22.         View view = root.getView(); 
  23.         if (view != null) { 
  24.             InputMethodManager imm = InputMethodManager.getInstance(); 
  25.             if (imm != null) { 
  26.                 imm.windowDismissed(mViews.get(index).getWindowToken()); 
  27.             } 
  28.         } 
  29.         boolean deferred = root.die(immediate); 
  30.         if (view != null) { 
  31.             view.assignParent(null); 
  32.             if (deferred) { 
  33.                 mDyingViews.add(view); 
  34.             } 
  35.         } 
  36.     } 

我們?cè)賮?lái)看看ViewRootImpl.die()方法的實(shí)現(xiàn);

 
 
 
 
  1. public final class ViewRootImpl implements ViewParent, 
  2.         View.AttachInfo.Callbacks, ThreadedRenderer.HardwareDrawCallbacks { 
  3.       boolean die(boolean immediate) { 
  4.             // Make sure we do execute immediately if we are in the middle of a traversal or the damage 
  5.             // done by dispatchDetachedFromWindow will cause havoc on return. 
  6.             //根據(jù)immediate參數(shù)來(lái)判斷是執(zhí)行異步刪除還是同步刪除 
  7.             if (immediate && !mIsInTraversal) { 
  8.                 doDie(); 
  9.                 return false; 
  10.             } 
  11.             if (!mIsDrawing) { 
  12.                 destroyHardwareRenderer(); 
  13.             } else { 
  14.                 Log.e(mTag, "Attempting to destroy the window while drawing!\n" + 
  15.                         "  window=" + this + ", title=" + mWindowAttributes.getTitle()); 
  16.             } 
  17.             //如果是異步刪除,則發(fā)送一個(gè)刪除View的消息MSG_DIE就會(huì)直接返回 
  18.             mHandler.sendEmptyMessage(MSG_DIE); 
  19.             return true; 
  20.         } 
  21.         void doDie() { 
  22.             checkThread(); 
  23.             if (LOCAL_LOGV) Log.v(mTag, "DIE in " + this + " of " + mSurface); 
  24.             synchronized (this) { 
  25.                 if (mRemoved) { 
  26.                     return; 
  27.                 } 
  28.                 mRemoved = true; 
  29.                 if (mAdded) { 
  30.                     //調(diào)用dispatchDetachedFromWindow()完成View的刪除 
  31.                     dispatchDetachedFromWindow(); 
  32.                 } 
  33.                 if (mAdded && !mFirst) { 
  34.                     destroyHardwareRenderer(); 
  35.                     if (mView != null) { 
  36.                         int viewVisibility = mView.getVisibility(); 
  37.                         boolean viewVisibilityChanged = mViewVisibility != viewVisibility; 
  38.                   
    當(dāng)前名稱:Android進(jìn)階:深入理解Android窗口管理框架機(jī)制
    網(wǎng)站鏈接:http://www.5511xx.com/article/ccopjeg.html