日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > Android >内容正文

Android

Android应用程序窗口(Activity)的视图对象(View)的创建过程分析

發(fā)布時間:2025/4/5 Android 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Android应用程序窗口(Activity)的视图对象(View)的创建过程分析 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

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

從前文可知道,每一個Activity組件都有一個關(guān)聯(lián)的Window對象,用來描述一個應(yīng)用程序窗口。每一個應(yīng)用程序窗口內(nèi)部又包含有一個View對象,用來描述應(yīng)用程序窗口的視圖。應(yīng)用程序窗口視圖是真正用來實現(xiàn)UI內(nèi)容和布局的,也就是說,每一個Activity組件的UI內(nèi)容和布局都是通過與其所關(guān)聯(lián)的一個Window對象的內(nèi)部的一個View對象來實現(xiàn)的。在本文中,我們就詳細(xì)分析應(yīng)用程序窗口視圖的創(chuàng)建過程。

?? ? ? 在前面Android應(yīng)用程序窗口(Activity)實現(xiàn)框架簡要介紹和學(xué)習(xí)計劃一文中提到,應(yīng)用程序窗口內(nèi)部所包含的視圖對象的實際類型為DecorView。DecorView類繼承了View類,是作為容器(ViewGroup)來使用的,它的實現(xiàn)如圖1所示:


圖1 DecorView類的實現(xiàn)

?? ? ? ?這個圖的具體描述可以參考Android應(yīng)用程序窗口(Activity)實現(xiàn)框架簡要介紹和學(xué)習(xí)計劃一文中的圖5,這里不再詳述。

?? ? ? ?從前面Android應(yīng)用程序窗口(Activity)實現(xiàn)框架簡要介紹和學(xué)習(xí)計劃一文還可以知道,每一個應(yīng)用程序窗口的視圖對象都有一個關(guān)聯(lián)的ViewRoot對象,這些關(guān)聯(lián)關(guān)系是由窗口管理器來維護(hù)的,如圖2所示:


圖2 應(yīng)用程序窗口視圖與ViewRoot的關(guān)系圖

?? ? ? ?這個圖的具體描述可以參考Android應(yīng)用程序窗口(Activity)實現(xiàn)框架簡要介紹和學(xué)習(xí)計劃一文中的圖6,這里不再詳述。

?? ? ? ?簡單來說,ViewRoot相當(dāng)于是MVC模型中的Controller,它有以下職責(zé):

?? ? ? ?1. 負(fù)責(zé)為應(yīng)用程序窗口視圖創(chuàng)建Surface。

?? ? ? ?2. 配合WindowManagerService來管理系統(tǒng)的應(yīng)用程序窗口。

?? ? ? ?3. 負(fù)責(zé)管理、布局和渲染應(yīng)用程序窗口視圖的UI。

?? ? ? ?那么,應(yīng)用程序窗口的視圖對象及其所關(guān)聯(lián)的ViewRoot對象是什么時候開始創(chuàng)建的呢? 從前面Android應(yīng)用程序窗口(Activity)的窗口對象(Window)的創(chuàng)建過程分析一 文可以知道,Activity組件在啟動的時候,系統(tǒng)會為它創(chuàng)建窗口對象(Window),同時,系統(tǒng)也會為這個窗口對象創(chuàng)建視圖對象。另一方面,當(dāng) Activity組件被激活的時候,系統(tǒng)如果發(fā)現(xiàn)與它的應(yīng)用程序窗口視圖對象所關(guān)聯(lián)的ViewRoot對象還沒有創(chuàng)建,那么就會先創(chuàng)建這個 ViewRoot對象,以便接下來可以將它的UI渲染出來。

?? ? ? 從前面Android應(yīng)用程序啟動過程源代碼分析一 文可以知道,Activity組件在啟動的過程中,會調(diào)用ActivityThread類的成員函數(shù)handleLaunchActivity,用來創(chuàng)建 以及首次激活A(yù)ctivity組件,因此,接下來我們就從這個函數(shù)開始,具體分析應(yīng)用程序窗口的視圖對象及其所關(guān)聯(lián)的ViewRoot對象的創(chuàng)建過程,如 圖3所示:


圖3 應(yīng)用程序窗口視圖的創(chuàng)建過程

?? ? ? ?這個過程一共可以分為13個步驟,接下來我們就詳細(xì)分析每一個步驟。

?? ? ? ?Step 1. ActivityThread.handleLaunchActivity

?

[java] view plaincopy
  • public?final?class?ActivityThread?{??
  • ????......??
  • ??
  • ????private?final?void?handleLaunchActivity(ActivityClientRecord?r,?Intent?customIntent)?{??
  • ????????......??
  • ??
  • ????????Activity?a?=?performLaunchActivity(r,?customIntent);??
  • ??
  • ????????if?(a?!=?null)?{??
  • ????????????......??
  • ??
  • ????????????handleResumeActivity(r.token,?false,?r.isForward);??
  • ??
  • ????????????......??
  • ????????}??
  • ??
  • ????????......??
  • ????}??
  • ??
  • ????......??
  • }??
  • ?? ? ? ?這個函數(shù)定義在文件frameworks/base/core/java/android/app/ActivityThread.java文件中。

    ?? ? ? ?函數(shù)首先調(diào)用ActivityThread類的成員函數(shù)performLaunchActivity來創(chuàng)建要啟動的Activity組件。在創(chuàng)建 Activity組件的過程中,還會為該Activity組件創(chuàng)建窗口對象和視圖對象。Activity組件創(chuàng)建完成之后,就可以將它激活起來了,這是通 過調(diào)用ActivityThread類的成員函數(shù)handleResumeActivity來執(zhí)行的。

    ?? ? ? ?接下來,我們首先分析ActivityThread類的成員函數(shù)performLaunchActivity的實現(xiàn),以便可以了解應(yīng)用程序窗口視圖對象 的創(chuàng)建過程,接著再回過頭來繼續(xù)分析ActivityThread類的成員函數(shù)handleResumeActivity的實現(xiàn),以便可以了解與應(yīng)用程序 窗口視圖對象所關(guān)聯(lián)的ViewRoot對象的創(chuàng)建過程。

    ?? ? ? ?Step 2.?ActivityThread.performLaunchActivity

    ?? ? ? ?這個函數(shù)定義在文件frameworks/base/core/java/android/app/ActivityThread.java文件中。

    ?? ? ? ?這一步可以參考Android應(yīng)用程序窗口(Activity)的運行上下文環(huán)境(Context)的創(chuàng)建過程分析一文的Step 1,它主要就是創(chuàng)建一個Activity組件實例,并且調(diào)用這個Activity組件實例的成員函數(shù)onCreate來讓其執(zhí)行一些自定義的初始化工作。

    ?? ? ? ?Step 3.?Activity.onCreate

    ?? ? ? ?這個函數(shù)定義在文件frameworks/base/core/java/android/app/Activity.java中。

    ?? ? ? ?這一步可以參考Android應(yīng)用程序窗口(Activity)的運行上下文環(huán)境(Context)的創(chuàng)建過程分析一文的Step 10。我們在實現(xiàn)一個Activity組件的時候,也就是在實現(xiàn)一個Activity子類的時候,一般都會重寫成員函數(shù)onCreate,以便可以執(zhí)行一些自定義的初始化工作,其中就包含初始化UI的工作。例如,在前面在Ubuntu上為Android系統(tǒng)內(nèi)置Java應(yīng)用程序測試Application Frameworks層的硬件服務(wù)一文中,我們實現(xiàn)了一個名稱為Hello的Activity組件,用來測試硬件服務(wù),它的成員函數(shù)onCreate的樣子長得大概如下所示:

    ?

    [java] view plaincopy
  • public?class?Hello?extends?Activity?implements?OnClickListener?{????
  • ????......????
  • ????????
  • ????/**?Called?when?the?activity?is?first?created.?*/????
  • ????@Override????
  • ????public?void?onCreate(Bundle?savedInstanceState)?{????
  • ????????super.onCreate(savedInstanceState);????
  • ????????setContentView(R.layout.main);????
  • ????
  • ????????......????
  • ????}????
  • ??
  • ????......??
  • }??
  • ?? ? ? 其中,調(diào)用從父類Activity繼承下來的成員函數(shù)setContentView就是用來創(chuàng)建應(yīng)用程序窗口視圖對象的。

    ?? ? ? 接下來,我們就繼續(xù)分析Activity類的成員函數(shù)setContentView的實現(xiàn)。

    ?? ? ? Step 4.?Activity.setContentView

    ?

    [java] view plaincopy
  • public?class?Activity?extends?ContextThemeWrapper??
  • ????????implements?LayoutInflater.Factory,??
  • ????????Window.Callback,?KeyEvent.Callback,??
  • ????????OnCreateContextMenuListener,?ComponentCallbacks?{??
  • ????......??
  • ??
  • ????private?Window?mWindow;??
  • ????......??
  • ??
  • ????public?Window?getWindow()?{??
  • ????????return?mWindow;??
  • ????}??
  • ????......??
  • ??
  • ????public?void?setContentView(int?layoutResID)?{??
  • ????????getWindow().setContentView(layoutResID);??
  • ????}??
  • ??
  • ????......??
  • }??
  • ?? ? ? ?這個函數(shù)定義在文件frameworks/base/core/java/android/app/Activity.java中。

    ?? ? ? ?Activity類的成員函數(shù)setContentView首先調(diào)用另外一個成員函數(shù)getWindow來獲得成員變量mWindow所描述的一個窗口 對象,接著再調(diào)用這個窗口對象的成員函數(shù)setContentView來執(zhí)行創(chuàng)建應(yīng)用程序窗口視圖對象的工作。

    ?? ? ? ?從前面Android應(yīng)用程序窗口(Activity)的窗口對象(Window)的創(chuàng)建過程分析一文可以知道,Activity類的成員變量mWindow指向的是一個PhoneWindow對象,因此,接下來我們就繼續(xù)分析PhoneWindow類的成員函數(shù)setContentView的實現(xiàn)。

    ?? ? ? ?Step 5. PhoneWindow.setContentView

    ?

    [java] view plaincopy
  • public?class?PhoneWindow?extends?Window?implements?MenuBuilder.Callback?{??
  • ????......??
  • ??
  • ????//?This?is?the?view?in?which?the?window?contents?are?placed.?It?is?either??
  • ????//?mDecor?itself,?or?a?child?of?mDecor?where?the?contents?go.??
  • ????private?ViewGroup?mContentParent;??
  • ????......??
  • ??
  • ????@Override??
  • ????public?void?setContentView(int?layoutResID)?{??
  • ????????if?(mContentParent?==?null)?{??
  • ????????????installDecor();??
  • ????????}?else?{??
  • ????????????mContentParent.removeAllViews();??
  • ????????}??
  • ????????mLayoutInflater.inflate(layoutResID,?mContentParent);??
  • ????????final?Callback?cb?=?getCallback();??
  • ????????if?(cb?!=?null)?{??
  • ????????????cb.onContentChanged();??
  • ????????}??
  • ????}??
  • ??
  • ????......??
  • }??
  • ?? ? ? ?這個函數(shù)定義在文件frameworks/base/policy/src/com/android/internal/policy/impl/PhoneWindow.java中。

    ?? ? ? ?PhoneWindow類的成員變量mContentParent用來描述一個類型為DecorView的視圖對象,或者這個類型為DecorView 的視圖對象的一個子視圖對象,用作UI容器。當(dāng)它的值等于null的時候,就說明正在處理的應(yīng)用程序窗口的視圖對象還沒有創(chuàng)建。在這種情況下,就會調(diào)用成 員函數(shù)installDecor來創(chuàng)建應(yīng)用程序窗口視圖對象。否則的話,就說明是要重新設(shè)置應(yīng)用程序窗口的視圖。在重新設(shè)置之前,首先調(diào)用成員變量 mContentParent所描述的一個ViewGroup對象來移除原來的UI內(nèi)空。

    ?? ? ? ?由于我們是在Activity組件啟動的過程中創(chuàng)建應(yīng)用程序窗口視圖的,因此,我們就假設(shè)此時PhoneWindow類的成員變量 mContentParent的值等于null。接下來,函數(shù)就會調(diào)用成員函數(shù)installDecor來創(chuàng)建應(yīng)用程序窗口視圖對象,接著再通過調(diào)用 PhoneWindow類的成員變量mLayoutInflater所描述的一個LayoutInflater對象的成員函數(shù)inflate來將參數(shù) layoutResID所描述的一個UI布局設(shè)置到前面所創(chuàng)建的應(yīng)用程序窗口視圖中去,最后還會調(diào)用一個Callback接口的成員函數(shù) onContentChanged來通知對應(yīng)的Activity組件,它的視圖內(nèi)容發(fā)生改變了。從前面Android應(yīng)用程序窗口(Activity)的窗口對象(Window)的創(chuàng)建過程分析一文可以知道,Activity組件自己實現(xiàn)了這個Callback接口,并且將這個Callback接口設(shè)置到了與它所關(guān)聯(lián)的應(yīng)用程序窗口對象的內(nèi)部去,因此,前面實際調(diào)用的是Activity類的成員函數(shù)onContentChanged來發(fā)出一個視圖內(nèi)容變化通知。

    ?? ? ?接下來,我們就繼續(xù)分析PhoneWindow類的成員函數(shù)installDecor的實現(xiàn),以便可以繼續(xù)了解應(yīng)用程序窗口視圖對象的創(chuàng)建過程。

    ?? ? ?Step 6.?PhoneWindow.installDecor

    ?

    [java] view plaincopy
  • public?class?PhoneWindow?extends?Window?implements?MenuBuilder.Callback?{??
  • ????......??
  • ??
  • ????//?This?is?the?top-level?view?of?the?window,?containing?the?window?decor.??
  • ????private?DecorView?mDecor;??
  • ????......??
  • ??
  • ????//?This?is?the?view?in?which?the?window?contents?are?placed.?It?is?either??
  • ????//?mDecor?itself,?or?a?child?of?mDecor?where?the?contents?go.??
  • ????private?ViewGroup?mContentParent;??
  • ????......??
  • ??
  • ????private?TextView?mTitleView;??
  • ????......??
  • ??
  • ????private?CharSequence?mTitle?=?null;??
  • ????......??
  • ??
  • ????private?void?installDecor()?{??
  • ????????if?(mDecor?==?null)?{??
  • ????????????mDecor?=?generateDecor();??
  • ????????????......??
  • ????????}??
  • ????????if?(mContentParent?==?null)?{??
  • ????????????mContentParent?=?generateLayout(mDecor);??
  • ??
  • ????????????mTitleView?=?(TextView)findViewById(com.android.internal.R.id.title);??
  • ????????????if?(mTitleView?!=?null)?{??
  • ????????????????if?((getLocalFeatures()?&?(1?<<?FEATURE_NO_TITLE))?!=?0)?{??
  • ????????????????????View?titleContainer?=?findViewById(com.android.internal.R.id.title_container);??
  • ????????????????????if?(titleContainer?!=?null)?{??
  • ????????????????????????titleContainer.setVisibility(View.GONE);??
  • ????????????????????}?else?{??
  • ????????????????????????mTitleView.setVisibility(View.GONE);??
  • ????????????????????}??
  • ????????????????????if?(mContentParent?instanceof?FrameLayout)?{??
  • ????????????????????????((FrameLayout)mContentParent).setForeground(null);??
  • ????????????????????}??
  • ????????????????}?else?{??
  • ????????????????????mTitleView.setText(mTitle);??
  • ????????????????}??
  • ????????????}??
  • ????????}??
  • ????}??
  • ??
  • ????......??
  • }??
  • ?? ? ? ?這個函數(shù)定義在文件frameworks/base/policy/src/com/android/internal/policy/impl/PhoneWindow.java中。

    ?? ? ? ?由于我們是在Activity組件啟動的過程中創(chuàng)建應(yīng)用程序窗口視圖的,因此,我們同時假設(shè)此時PhoneWindow類的成員變量mDecor的值等 于null。這時候PhoneWindow類的成員函數(shù)installDecor就會調(diào)用另外一個成員函數(shù)generateDecor來創(chuàng)建一個 DecorView對象,并且保存在PhoneWindow類的成員變量mDecor中。

    ?? ? ? ?PhoneWindow類的成員函數(shù)installDecor接著再調(diào)用另外一個成員函數(shù)generateLayout來根據(jù)當(dāng)前應(yīng)用程序窗口的 Feature來加載對應(yīng)的窗口布局文件。這些布局文件保存在frameworks/base/core/res/res/layout目錄下,它們必須 包含有一個id值為“content”的布局控件。這個布局控件必須要從ViewGroup類繼承下來,用來作為窗口的UI容器。PhoneWindow 類的成員函數(shù)generateLayout執(zhí)行完成之后,就會這個id值為“content”的ViewGroup控件來給PhoneWindow類的成 員函數(shù)installDecor,后者再將其保存在成員變量mContentParent中。

    ?? ? ? PhoneWindow類的成員函數(shù)installDecor還會檢查前面加載的窗口布局文件是否包含有一個id值為“title”的TextView控 件。如果包含有的話,就會將它保存在PhoneWindow類的成員變量mTitleView中,用來描述當(dāng)前應(yīng)用程序窗口的標(biāo)題欄。但是,如果當(dāng)前應(yīng)用 程序窗口是沒有標(biāo)題欄的,即它的Feature位FEATURE_NO_TITLE的值等于1,那么PhoneWindow類的成員函數(shù) installDecor就需要將前面得到的標(biāo)題欄隱藏起來。注意,PhoneWindow類的成員變量mTitleView所描述的標(biāo)題欄有可能是包含 在一個id值為“title_container”的容器里面的,在這種情況下,就需要隱藏該標(biāo)題欄容器。另一方面,如果當(dāng)前應(yīng)用程序窗口是設(shè)置有標(biāo)題欄 的,那么PhoneWindow類的成員函數(shù)installDecor就會設(shè)置它的標(biāo)題欄文字。應(yīng)用程序窗口的標(biāo)題欄文字保存在PhoneWindow類 的成員變量mTitle中,我們可以調(diào)用PhoneWindow類的成員函數(shù)setTitle來設(shè)置。

    ?? ? ? 這一步執(zhí)行完成之后,應(yīng)用程序窗口視圖就創(chuàng)建完成了,回到前面的Step 1中,即ActivityThread類的成員函數(shù)handleLaunchActivity中,接下來就會調(diào)用ActivityThread類的另外一 個成員函數(shù)handleResumeActivity來激活正在啟動的Activity組件。由于在是第一次激活該Activity組件,因此,在激活之 前,還會為該Activity組件創(chuàng)建一個ViewRoot對象,并且與前面所創(chuàng)建的應(yīng)用程序窗口視圖關(guān)聯(lián)起來,以便后面可以通過該ViewRoot對象 來控制應(yīng)用程序窗口視圖的UI展現(xiàn)。

    ?? ? ? 接下來,我們就繼續(xù)分析ActivityThread類的成員函數(shù)handleResumeActivity的實現(xiàn)。

    ?? ? ? Step 7.?ActivityThread.handleResumeActivity

    ?

    [java] view plaincopy
  • public?final?class?ActivityThread?{??
  • ????......??
  • ??
  • ????final?void?handleResumeActivity(IBinder?token,?boolean?clearHide,?boolean?isForward)?{??
  • ????????......??
  • ??
  • ????????ActivityClientRecord?r?=?performResumeActivity(token,?clearHide);??
  • ??
  • ????????if?(r?!=?null)?{??
  • ????????????final?Activity?a?=?r.activity;??
  • ????????????......??
  • ??
  • ????????????//?If?the?window?hasn't?yet?been?added?to?the?window?manager,??
  • ????????????//?and?this?guy?didn't?finish?itself?or?start?another?activity,??
  • ????????????//?then?go?ahead?and?add?the?window.??
  • ????????????boolean?willBeVisible?=?!a.mStartedActivity;??
  • ????????????if?(!willBeVisible)?{??
  • ????????????????try?{??
  • ????????????????????willBeVisible?=?ActivityManagerNative.getDefault().willActivityBeVisible(??
  • ????????????????????????????a.getActivityToken());??
  • ????????????????}?catch?(RemoteException?e)?{??
  • ????????????????}??
  • ????????????}??
  • ????????????if?(r.window?==?null?&&?!a.mFinished?&&?willBeVisible)?{??
  • ????????????????r.window?=?r.activity.getWindow();??
  • ????????????????View?decor?=?r.window.getDecorView();??
  • ????????????????decor.setVisibility(View.INVISIBLE);??
  • ????????????????ViewManager?wm?=?a.getWindowManager();??
  • ????????????????WindowManager.LayoutParams?l?=?r.window.getAttributes();??
  • ????????????????a.mDecor?=?decor;??
  • ????????????????l.type?=?WindowManager.LayoutParams.TYPE_BASE_APPLICATION;??
  • ????????????????......??
  • ????????????????if?(a.mVisibleFromClient)?{??
  • ????????????????????a.mWindowAdded?=?true;??
  • ????????????????????wm.addView(decor,?l);??
  • ????????????????}??
  • ????????????}???
  • ??
  • ????????????......??
  • ????????}??
  • ??
  • ????????......??
  • ????}??
  • ????
  • ????......??
  • }??
  • ?? ? ? ?這個函數(shù)定義在文件frameworks/base/core/java/android/app/ActivityThread.java中。

    ?? ? ? ?ActivityThread類的成員函數(shù)handleResumeActivity首先調(diào)用另外一個成員函數(shù) performResumeActivity來通知Activity組件,它要被激活了,即會導(dǎo)致Activity組件的成員函數(shù)onResume被調(diào) 用。ActivityThread類的成員函數(shù)performResumeActivity的返回值是一個ActivityClientRecord對象 r,這個ActivityClientRecord對象的成員變量activity描述的就是正在激活的Activity組件a。

    ?? ? ? ?ActivityThread類的成員函數(shù)handleResumeActivity接下來判斷正在激活的Activity組件接下來是否是可見的。如 果是可見的,那么變量willBeVisible的值就會等于true。Activity類的成員變量mStartedActivity用來描述一個 Activity組件是否正在啟動一個新的Activity組件,并且等待這個新的Activity組件的執(zhí)行結(jié)果。如果是的話,那么這個 Activity組件的成員變量mStartedActivity的值就會等于true,表示在新的Activity組件的執(zhí)行結(jié)果返回來之前,當(dāng)前 Activity組件要保持不可見的狀態(tài)。因此,當(dāng)Activity組件a的成員變量mStartedActivity的值等于true的時候,它接下來 就是不可見的,否則的話,就是可見的。

    ?? ? ? ?雖然說在Activity組件a的成員變量mStartedActivity的值等于true的情況下,它接下來的狀態(tài)要保持不可見的,但是有可能它所 啟動的Activity組件的UI不是全屏的。在這種情況下,Activity組件a的UI仍然是有部分可見的,這時候也要將變量 willBeVisible的值設(shè)置為true。因此,如果前面得到變量willBeVisible的值等于false,那么 ActivityThread類的成員函數(shù)handleResumeActivity接下來就會通過Binder進(jìn)程間通信機(jī)制來調(diào)用 ActivityManagerService服務(wù)的成員函數(shù)willActivityBeVisible來檢查位于Activity組件a上面的其它 Activity組件(包含了Activity組件a正在等待其執(zhí)行結(jié)果的Activity組件)是否是全屏的。如果不是,那么 ActivityManagerService服務(wù)的成員函數(shù)willActivityBeVisible的返回值就會等于true,表示接下來需要顯示 Activity組件a。

    ?? ? ? 前面得到的ActivityClientRecord對象r的成員變量window用來描述當(dāng)前正在激活的Activity組件a所關(guān)聯(lián)的應(yīng)用程序窗口對 象。當(dāng)它的值等于null的時候,就表示當(dāng)前正在激活的Activity組件a所關(guān)聯(lián)的應(yīng)用程序窗口對象還沒有關(guān)聯(lián)一個ViewRoot對象。進(jìn)一步地, 如果這個正在激活的Activity組件a還活著,并且接下來是可見的,即ActivityClientRecord對象r的成員變量mFinished 的值等于false,并且前面得到的變量willBeVisible的值等于true,那么這時候就說明需要為與Activity組件a所關(guān)聯(lián)的一個應(yīng)用 程序窗口視圖對象關(guān)聯(lián)的一個ViewRoot對象。

    ?? ? ? 將一個Activity組件的應(yīng)用程序窗口視圖對象與一個ViewRoot對象關(guān)聯(lián)是通過該Activity組件所使用的窗口管理器來執(zhí)行的。從前面Android應(yīng)用程序窗口(Activity)的窗口對象(Window)的創(chuàng)建過程分析一 文可以知道,一個Activity組件所使用的本地窗口管理器保存它的成員變量mWindowManager中,這可以通過Activity類的成員函數(shù) getWindowManager來獲得。在接下來的Step 10中,我們再分析Activity類的成員函數(shù)getWindowManager的實現(xiàn)。

    ?? ? ? 由于我們現(xiàn)在要給Activity組件a的應(yīng)用程序窗口視圖對象關(guān)聯(lián)一個ViewRoot對象,因此,我們就需要首先獲得這個應(yīng)用程序窗口視圖對象。從前 面的Step 6可以知道,一個Activity組件的應(yīng)用程序窗口視圖對象保存在與其所關(guān)聯(lián)的一個應(yīng)用程序窗口對象的內(nèi)部,因此,我們又要首先獲得這個應(yīng)用程序窗口對 象。與一個Activity組件所關(guān)聯(lián)的應(yīng)用程序窗口對象可以通過調(diào)用該Activity組件的成員函數(shù)getWindow來獲得。一旦獲得了這個應(yīng)用程 序窗口對象(類型為PhoneWindow)之后,我們就可以調(diào)用它的成員函數(shù)getDecorView來獲得它內(nèi)部的視圖對象。在接下來的Step 8和Step 9中,我們再分別分析Activity類的成員函數(shù)Activity類的成員函數(shù)getWindow和PhoneWindow類的成員函數(shù) getDecorView的實現(xiàn)。

    ?? ? ?在關(guān)聯(lián)應(yīng)用程序窗口視圖對象和ViewRoot對象的時候,還需要第三個參數(shù),即應(yīng)用程序窗口的布局參數(shù),這是一個類型為 WindowManager.LayoutParams的對象,可以通過調(diào)用應(yīng)用程序窗口的成員函數(shù)getAttributes來獲得。一切準(zhǔn)備就緒之 后,還要判斷最后一個條件是否成立,即當(dāng)前正在激活的Activity組件a在本地進(jìn)程中是否是可見的,即它的成員變量 mVisibleFromClient的值是否等于true。如果是可見的,那么最后就可以調(diào)用前面所獲得的一個本地窗口管理器wm(類型為 LocalWindowManager)的成員函數(shù)addView來執(zhí)行關(guān)聯(lián)應(yīng)用程序窗口視圖對象和ViewRoot對象的操作。

    ?? ? 接下來,我們就分別分析Activity類的成員函數(shù)getWindow、PhoneWindow類的成員函數(shù)getDecorView、ctivity 類的成員函數(shù)getWindowManager以及LocalWindowManager類的成員函數(shù)addView的實現(xiàn)。

    ?? ? Step 8.?Activity.getWindow

    [java] view plaincopy
  • public?class?Activity?extends?ContextThemeWrapper??
  • ????????implements?LayoutInflater.Factory,??
  • ????????Window.Callback,?KeyEvent.Callback,??
  • ????????OnCreateContextMenuListener,?ComponentCallbacks?{??
  • ????......??
  • ??
  • ????private?Window?mWindow;??
  • ????......??
  • ??
  • ????public?Window?getWindow()?{??
  • ????????return?mWindow;??
  • ????}??
  • ??
  • ????......??
  • }??
  • ?? ? ? ?這個函數(shù)定義在文件frameworks/base/core/java/android/app/Activity.java中。

    ?? ? ? ?從前面Android應(yīng)用程序窗口(Activity)的窗口對象(Window)的創(chuàng)建過程分析一文可以知道,Activity類的成員變量mWindow指向的是一個類型為PhoneWindow的窗口對象,因此,Activity類的成員函數(shù)getWindow返回給調(diào)用者的是一個PhoneWindow對象。

    ?? ? ? ?這一步執(zhí)完成之后,返回到前面的Step 7中,即ActivityThread類的成員函數(shù)handleResumeActivity中,接下來就會繼續(xù)調(diào)用前面所獲得的一個 PhoneWindow對象的成員函數(shù)getDecorView來獲得當(dāng)前正在激活的Activity組件所關(guān)聯(lián)的一個應(yīng)用程序窗口視圖對象。

    ?? ? ? ?Step 9.?PhoneWindow.getDecorView

    [java] view plaincopy
  • public?class?PhoneWindow?extends?Window?implements?MenuBuilder.Callback?{??
  • ????......??
  • ??
  • ????private?DecorView?mDecor;??
  • ????......??
  • ??
  • ????@Override??
  • ????public?final?View?getDecorView()?{??
  • ????????if?(mDecor?==?null)?{??
  • ????????????installDecor();??
  • ????????}??
  • ????????return?mDecor;??
  • ????}??
  • ??
  • ????......??
  • }??
  • ?? ? ? ?這個函數(shù)定義在文件frameworks/base/policy/src/com/android/internal/policy/impl/PhoneWindow.java中。

    ?? ? ? ?PhoneWindow類的成員函數(shù)getDecorView首先判斷成員變量mDecor的值是否等于null。如果是的話,那么就說明當(dāng)前正在處理 的應(yīng)用程序窗口還沒有創(chuàng)建視圖對象。這時候就會調(diào)用另外一個成員函數(shù)installDecor來創(chuàng)建這個視圖對象。從前面的調(diào)用過程可以知道,當(dāng)前正在處 理的應(yīng)用程序窗口已經(jīng)創(chuàng)建過視圖對象,因此,這里的成員變量mDecor的值不等于null,PhoneWindow類的成員函數(shù) getDecorView直接將它返回給調(diào)用者。

    ?? ? ? ?這一步執(zhí)完成之后,返回到前面的Step 7中,即ActivityThread類的成員函數(shù)handleResumeActivity中,接下來就會繼續(xù)調(diào)用當(dāng)前正在激活的Activity組件 的成員函數(shù)getWindowManager來獲得一個本地窗口管理器。

    ?? ? ? ?Step 10.?Activity.getWindowManager

    [java] view plaincopy
  • public?class?Activity?extends?ContextThemeWrapper??
  • ????????implements?LayoutInflater.Factory,??
  • ????????Window.Callback,?KeyEvent.Callback,??
  • ????????OnCreateContextMenuListener,?ComponentCallbacks?{??
  • ????......??
  • ??
  • ????private?WindowManager?mWindowManager;??
  • ????......??
  • ??
  • ????public?WindowManager?getWindowManager()?{??
  • ????????return?mWindowManager;??
  • ????}??
  • ??
  • ????......??
  • }??
  • ?? ? ? ?這個函數(shù)定義在文件frameworks/base/core/java/android/app/Activity.java中。

    ?? ? ? ?從前面Android應(yīng)用程序窗口(Activity)的運行上下文環(huán)境(Context)的創(chuàng)建過程分析一文可以知道,Activity類的成員變量mWindowManager指向的一是類型為LocalWindowManager的本地窗口管理器,Activity類的成員函數(shù)getWindowManager直接將它返回給調(diào)用者。

    ?? ? ? ?這一步執(zhí)完成之后,返回到前面的Step 7中,即ActivityThread類的成員函數(shù)handleResumeActivity中,接下來就會繼續(xù)調(diào)用前面所獲得的一個 LocalWindowManager對象的成員函數(shù)addView來為當(dāng)前正在激活的Activity組件的應(yīng)用程序窗口視圖對象關(guān)聯(lián)一個 ViewRoot對象。

    ?? ? ? ?Step 11.?LocalWindowManager.addView

    [java] view plaincopy
  • public?abstract?class?Window?{??
  • ????......??
  • ??
  • ????private?class?LocalWindowManager?implements?WindowManager?{??
  • ????????......??
  • ??
  • ????????public?final?void?addView(View?view,?ViewGroup.LayoutParams?params)?{??
  • ????????????......??
  • ??
  • ????????????mWindowManager.addView(view,?params);??
  • ????????}??
  • ??
  • ????????......??
  • ??
  • ????????private?final?WindowManager?mWindowManager;??
  • ???
  • ????????......??
  • ????}??
  • ??
  • ????......??
  • }??
  • ?? ? ? ?這個函數(shù)定義在文件frameworks/base/core/java/android/view/Window.java中。

    ?? ? ? ?從前面Android應(yīng)用程序窗口(Activity)的窗口對象(Window)的創(chuàng)建過程分析一 文可以知道,LocalWindowManager類的成員變量mWindowManager指向的是一個WindowManagerImpl對象,因 此,LocalWindowManager類的成員函數(shù)addView接下來調(diào)用WindowManagerImpl類的成員函數(shù)addView來給參數(shù) view所描述的一個應(yīng)用程序窗口視圖對象關(guān)聯(lián)一個ViewRoot對象。

    ?? ? ? ?Step 12.?WindowManagerImpl.addView

    [java] view plaincopy
  • public?class?WindowManagerImpl?implements?WindowManager?{??
  • ????......??
  • ??
  • ????public?void?addView(View?view,?ViewGroup.LayoutParams?params)??
  • ????{??
  • ????????addView(view,?params,?false);??
  • ????}??
  • ??
  • ????......??
  • ??
  • ????private?void?addView(View?view,?ViewGroup.LayoutParams?params,?boolean?nest)??
  • ????{??
  • ????????......??
  • ??
  • ????????final?WindowManager.LayoutParams?wparams??
  • ????????????????=?(WindowManager.LayoutParams)params;??
  • ??
  • ????????ViewRoot?root;??
  • ????????View?panelParentView?=?null;??
  • ??
  • ????????synchronized?(this)?{??
  • ????????????//?Here's?an?odd/questionable?case:?if?someone?tries?to?add?a??
  • ????????????//?view?multiple?times,?then?we?simply?bump?up?a?nesting?count??
  • ????????????//?and?they?need?to?remove?the?view?the?corresponding?number?of??
  • ????????????//?times?to?have?it?actually?removed?from?the?window?manager.??
  • ????????????//?This?is?useful?specifically?for?the?notification?manager,??
  • ????????????//?which?can?continually?add/remove?the?same?view?as?a??
  • ????????????//?notification?gets?updated.??
  • ????????????int?index?=?findViewLocked(view,?false);??
  • ????????????if?(index?>=?0)?{??
  • ????????????????if?(!nest)?{??
  • ????????????????????throw?new?IllegalStateException("View?"?+?view??
  • ????????????????????????????+?"?has?already?been?added?to?the?window?manager.");??
  • ????????????????}??
  • ????????????????root?=?mRoots[index];??
  • ????????????????root.mAddNesting++;??
  • ????????????????//?Update?layout?parameters.??
  • ????????????????view.setLayoutParams(wparams);??
  • ????????????????root.setLayoutParams(wparams,?true);??
  • ????????????????return;??
  • ????????????}??
  • ??
  • ????????????//?If?this?is?a?panel?window,?then?find?the?window?it?is?being??
  • ????????????//?attached?to?for?future?reference.??
  • ????????????if?(wparams.type?>=?WindowManager.LayoutParams.FIRST_SUB_WINDOW?&&??
  • ????????????????????wparams.type?<=?WindowManager.LayoutParams.LAST_SUB_WINDOW)?{??
  • ????????????????final?int?count?=?mViews?!=?null???mViews.length?:?0;??
  • ????????????????for?(int?i=0;?i<count;?i++)?{??
  • ????????????????????if?(mRoots[i].mWindow.asBinder()?==?wparams.token)?{??
  • ????????????????????????panelParentView?=?mViews[i];??
  • ????????????????????}??
  • ????????????????}??
  • ????????????}??
  • ??
  • ????????????root?=?new?ViewRoot(view.getContext());??
  • ????????????root.mAddNesting?=?1;??
  • ??
  • ????????????view.setLayoutParams(wparams);??
  • ??
  • ????????????if?(mViews?==?null)?{??
  • ????????????????index?=?1;??
  • ????????????????mViews?=?new?View[1];??
  • ????????????????mRoots?=?new?ViewRoot[1];??
  • ????????????????mParams?=?new?WindowManager.LayoutParams[1];??
  • ????????????}?else?{??
  • ????????????????index?=?mViews.length?+?1;??
  • ????????????????Object[]?old?=?mViews;??
  • ????????????????mViews?=?new?View[index];??
  • ????????????????System.arraycopy(old,?0,?mViews,?0,?index-1);??
  • ????????????????old?=?mRoots;??
  • ????????????????mRoots?=?new?ViewRoot[index];??
  • ????????????????System.arraycopy(old,?0,?mRoots,?0,?index-1);??
  • ????????????????old?=?mParams;??
  • ????????????????mParams?=?new?WindowManager.LayoutParams[index];??
  • ????????????????System.arraycopy(old,?0,?mParams,?0,?index-1);??
  • ????????????}??
  • ????????????index--;??
  • ??
  • ????????????mViews[index]?=?view;??
  • ????????????mRoots[index]?=?root;??
  • ????????????mParams[index]?=?wparams;??
  • ????????}??
  • ????????//?do?this?last?because?it?fires?off?messages?to?start?doing?things??
  • ????????root.setView(view,?wparams,?panelParentView);??
  • ????}??
  • ??
  • ????......??
  • ??
  • ????private?View[]?mViews;??
  • ????private?ViewRoot[]?mRoots;??
  • ????private?WindowManager.LayoutParams[]?mParams;??
  • ??
  • ????......??
  • }??
  • ?? ? ? 這個函數(shù)定義在文件frameworks/base/core/java/android/view/WindowManagerImpl.java中。

    ?? ? ? 在WindowManagerImpl類中,兩個參數(shù)版本的成員函數(shù)addView是通過調(diào)用三個參數(shù)版本的成同函數(shù)addView來實現(xiàn)的,因此,我們接下來就主要分析三個參數(shù)版本的成員函數(shù)addView的實現(xiàn)。

    ?? ? ? 在分析WindowManagerImpl類的三個參數(shù)版本的成員函數(shù)addView的實現(xiàn)之前,我們首先了解一下WindowManagerImpl類 是如何關(guān)聯(lián)一個應(yīng)用程序窗口視圖對象(View對象)和一個ViewRoot對象的。一個View對象在與一個ViewRoot對象關(guān)聯(lián)的同時,還會關(guān)聯(lián) 一個WindowManager.LayoutParams對象,這個WindowManager.LayoutParams對象是用來描述應(yīng)用程序窗口 視圖的布局屬性的。

    ?? ? ??WindowManagerImpl類有三個成員變量mViews、mRoots和mParams,它們分別是類型為View、ViewRoot和 WindowManager.LayoutParams的數(shù)組。這三個數(shù)組的大小是始終保持相等的。這樣, 有關(guān)聯(lián)關(guān)系的View對象、ViewRoot對象和WindowManager.LayoutParams對象就會分別保存在數(shù)組mViews、 mRoots和mParams的相同位置上,也就是說,mViews[i]、mRoots[i]和mParams[i]所描述的View對象、 ViewRoot對象和WindowManager.LayoutParams對象是具有關(guān)聯(lián)關(guān)系的。因此,WindowManagerImpl類的三個 參數(shù)版本的成員函數(shù)addView在關(guān)聯(lián)一個View對象、一個ViewRoot對象和一個WindowManager.LayoutParams對象的 時候,只要分別將它們放在數(shù)組mViews、mRoots和mParams的相同位置上就可以了。

    ?? ? ? 理解了一個View對象、一個ViewRoot對象和一個WindowManager.LayoutParams對象是如何關(guān)聯(lián)之后,WindowManagerImpl類的三個參數(shù)版本的成員函數(shù)addView的實現(xiàn)就容易理解了。

    ?? ? ? 參數(shù)view和參數(shù)params描述的就是要關(guān)聯(lián)的View對象和WindowManager.LayoutParams對象。成員函數(shù)addView首 先調(diào)用另外一個成員函數(shù)findViewLocked來檢查參數(shù)view所描述的一個View對象是否已經(jīng)存在于數(shù)組中mViews中了。如果已經(jīng)存在的 話,那么就說明該View對象已經(jīng)關(guān)聯(lián)過ViewRoot對象以及WindowManager.LayoutParams對象了。在這種情況下,如果參數(shù) nest的值等于false,那么成員函數(shù)addView是不允許重復(fù)對參數(shù)view所描述的一個View對象進(jìn)行重新關(guān)聯(lián)的。另一方面,如果參數(shù) nest的值等于true,那么成員函數(shù)addView只是重新修改參數(shù)view所描述的一個View對象及其所關(guān)聯(lián)的一個ViewRoot對象內(nèi)部使用 的一個WindowManager.LayoutParams對象,即更新為參數(shù)params所描述的一個 WindowManager.LayoutParams對象,這是通過調(diào)用它們的成員函數(shù)setLayoutParams來實現(xiàn)的。

    ?? ? ? 如果參數(shù)view所描述的一個View對象還沒有被關(guān)聯(lián)過一個ViewRoot對象,那么成員函數(shù)addView就會創(chuàng)建一個ViewRoot對象,并且 將它與參數(shù)view和params分別描述的一個View對象和一個WindowManager.LayoutParams對象保存在數(shù)組mViews、 mRoots和mParams的相同位置上。注意,如果數(shù)組mViews、mRoots和mParams尚未創(chuàng)建,那么成員函數(shù)addView就會首先分 別為它們創(chuàng)建一個大小為1的數(shù)組,以便可以用來分別保存所要關(guān)聯(lián)的View對象、ViewRoot對象和 WindowManager.LayoutParams對象。另一方面,如果數(shù)組mViews、mRoots和mParams已經(jīng)創(chuàng)建,那么成員函數(shù) addView就需要分別將它們的大小增加1,以便可以在它們的末尾位置上分別保存所要關(guān)聯(lián)的View對象、ViewRoot對象和 WindowManager.LayoutParams對象。

    ?? ? ? 還有另外一個需要注意的地方是當(dāng)參數(shù)view描述的是一個子應(yīng)用程序窗口的視圖對象時,即WindowManager.LayoutParams對象 wparams的成員變量type的值大于等于WindowManager.LayoutParams.FIRST_SUB_WINDOW并且小于等于 WindowManager.LayoutParams.LAST_SUB_WINDOW時,那么成員函數(shù)addView還需要找到這個子視圖對象的父視 圖對象panelParentView,這是通過遍歷數(shù)組mRoots來查找的。首先,WindowManager.LayoutParams對象 wparams的成員變量token指向了一個類型為W的Binder本地對象的一個IBinder接口,用來描述參數(shù)view所描述的一個子應(yīng)用程序窗 口視圖對象所屬的父應(yīng)用程序窗口視圖對象。其次,每一個ViewRoot對象都通過其成員變量mWindow來保存一個類型為W的Binder本地對象, 因此,如果在數(shù)組mRoots中,存在一個ViewRoot對象,它的成員變量mWindow所描述的一個W對象的一個IBinder接口等于 WindowManager.LayoutParams對象wparams的成員變量token所描述的一個IBinder接口時,那么就說明與該 ViewRoot對象所關(guān)聯(lián)的View對象即為參數(shù)view的父應(yīng)用程序窗口視圖對象。

    ?? ? ? ?成員函數(shù)addView為參數(shù)view所描述的一個View對象和參數(shù)params所描述的一個WindowManager.LayoutParams 對象關(guān)聯(lián)好一個ViewRoot對象root之后,最后還會將這個View對view象和這個WindowManager.LayoutParams對 象,以及變量panelParentView所描述的一個父應(yīng)用程序窗視圖對象,保存在這個ViewRoot對象root的內(nèi)部去,這是通過調(diào)用這個 ViewRoot對象root的成員函數(shù)setView來實現(xiàn)的,因此,接下來我們就繼續(xù)分析ViewRoot類的成員函數(shù)setView的實現(xiàn)。

    ?? ? ? ?Step 13. ViewRoot.setView

    [java] view plaincopy
  • public?final?class?ViewRoot?extends?Handler?implements?ViewParent,??
  • ????????View.AttachInfo.Callbacks?{??
  • ????......??
  • ??
  • ????final?WindowManager.LayoutParams?mWindowAttributes?=?new?WindowManager.LayoutParams();??
  • ????......??
  • ??
  • ????View?mView;??
  • ????......??
  • ??
  • ????final?View.AttachInfo?mAttachInfo;??
  • ????......??
  • ??
  • ????boolean?mAdded;??
  • ????......??
  • ??
  • ????public?void?setView(View?view,?WindowManager.LayoutParams?attrs,??
  • ????????????View?panelParentView)?{??
  • ????????synchronized?(this)?{??
  • ????????????if?(mView?==?null)?{??
  • ????????????????mView?=?view;??
  • ????????????????mWindowAttributes.copyFrom(attrs);??
  • ????????????????......??
  • ??
  • ????????????????mAttachInfo.mRootView?=?view;??
  • ????????????????.......??
  • ??
  • ????????????????if?(panelParentView?!=?null)?{??
  • ????????????????????mAttachInfo.mPanelParentWindowToken??
  • ????????????????????????????=?panelParentView.getApplicationWindowToken();??
  • ????????????????}??
  • ????????????????mAdded?=?true;??
  • ????????????????......??
  • ??
  • ????????????????requestLayout();??
  • ????????????????......??
  • ????????????????try?{??
  • ????????????????????res?=?sWindowSession.add(mWindow,?mWindowAttributes,??
  • ????????????????????????????getHostVisibility(),?mAttachInfo.mContentInsets,??
  • ????????????????????????????mInputChannel);??
  • ????????????????}?catch?(RemoteException?e)?{??
  • ????????????????????mAdded?=?false;??
  • ????????????????????mView?=?null;??
  • ????????????????????......??
  • ????????????????????throw?new?RuntimeException("Adding?window?failed",?e);??
  • ????????????????}?finally?{??
  • ????????????????????if?(restore)?{??
  • ????????????????????????attrs.restore();??
  • ????????????????????}??
  • ????????????????}??
  • ??
  • ????????????????......??
  • ????????????}??
  • ??
  • ????????????......??
  • ????????}??
  • ????}??
  • ??
  • ????......??
  • }??
  • ?? ? ? ?這個函數(shù)定義在文件frameworks/base/core/java/android/view/ViewRoot.java中。

    ?? ? ? ?參數(shù)view所描述的一個View對象會分別被保存在ViewRoot類的成員變量mView以及成員變量mAttachInfo所描述的一個 AttachInfo的成員變量mRootView中,而參數(shù)attrs所描述的一個WindowManager.LayoutParams對象的內(nèi)容會 被拷貝到ViewRoot類的成員變量mWindowAttributes中去。

    ?? ? ? 當(dāng)參數(shù)panelParentView的值不等于null的時候,就表示參數(shù)view描述的是一個子應(yīng)用程序窗口視圖對象。在這種情況下,參數(shù) panelParentView描述的就是一個父應(yīng)用程序窗口視圖對象。這時候我們就需要獲得用來描述這個父應(yīng)用程序窗口視圖對象的一個類型為W的 Binder本地對象的IBinder接口,以便可以保存在ViewRoot類的成員變量mAttachInfo所描述的一個AttachInfo的成員 變量mPanelParentWindowToken中去。這樣以后就可以知道ViewRoot類的成員變量mView所描述的一個子應(yīng)用程序窗口視圖所 屬的父應(yīng)用程序窗口視圖是什么了。注意,通過調(diào)用參數(shù)panelParentView的所描述的一個View對象的成員函數(shù) getApplicationWindowToken即可以獲得一個對應(yīng)的W對象的IBinder接口。

    ?? ? ? 上述操作執(zhí)行完成之后,ViewRoot類的成員函數(shù)setView就可以將成員變量mAdded的值設(shè)置為true了,表示當(dāng)前正在處理的一個 ViewRoot對象已經(jīng)關(guān)聯(lián)好一個View對象了。接下來,ViewRoot類的成員函數(shù)setView還需要執(zhí)行兩個操作:

    ?? ? ? 1. 調(diào)用ViewRoot類的另外一個成員函數(shù)requestLayout來請求對應(yīng)用程序窗口視圖的UI作第一次布局。

    ?? ? ? 2. 調(diào)用ViewRoot類的靜態(tài)成員變量sWindowSession所描述的一個類型為Session的Binder代理對象的成員函數(shù)add來請求 WindowManagerService增加一個WindowState對象,以便可以用來描述當(dāng)前正在處理的一個ViewRoot所關(guān)聯(lián)的一個應(yīng)用程 序窗口。

    ?? ? ? 至此,我們就分析完成Android應(yīng)用程序窗口視圖對象的創(chuàng)建過程了。在接下來的一篇文章中,我們將會繼續(xù)分析Android應(yīng)用程序窗口與 WindowManagerService服務(wù)的連接過程,即Android應(yīng)用程序窗口請求WindowManagerService為其增加一個 WindowState對象的過程,而在接下來的兩篇文章中,我們還會分析用來渲染Android應(yīng)用程序窗口的Surface的創(chuàng)建過程,以及 Android應(yīng)用程序窗口的渲染過程。通過這三個過程的分析,我們就可以看到上述第1點和第2點提到的兩個函數(shù)的執(zhí)行過程,敬請期待!

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

    總結(jié)

    以上是生活随笔為你收集整理的Android应用程序窗口(Activity)的视图对象(View)的创建过程分析的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

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

    主站蜘蛛池模板: av电影在线播放 | 亚洲生活片| 请用你的手指扰乱我吧 | 久草视频福利在线 | 久草精品在线观看视频 | 久久久久久久久亚洲 | 精品久久久久成人码免费动漫 | 91国内| 亚洲爽片 | 天天干夜夜做 | 99久久影视 | 久草视频在线免费 | 欧美日本免费 | 九九在线观看免费高清版 | 精品人妻二区中文字幕 | 99re99| 一区二区免费在线播放 | 欧美精品在线一区 | 狠狠艹av| 国产乱淫视频 | 狂野欧美性猛交blacked | 老熟女毛茸茸浓毛 | 一级片大片 | 日本激情视频在线 | 狠狠做深爱婷婷久久综合一区 | 又大又硬又爽免费视频 | 日本三区视频 | 亚洲天堂福利视频 | 美女被爆操网站 | 香蕉综合视频 | 婷婷婷色| 免费中文字幕日韩 | 激情久久av一区av二区av三区 | 永久免费不卡在线观看黄网站 | 中文在线а√天堂官网 | 蜜桃视频网站 | 狠狠摸狠狠操 | 一区高清| 欧美精品一区二区免费看 | 亚洲国产影视 | av免费视屏 | 白丝一区 | 已满十八岁免费观看全集动漫 | 三级特黄 | 韩国一二三区 | 国产黄色片在线观看 | 国模av| 日韩精品极品视频在线观看免费 | 久久亚洲日本 | 色狠狠久久av大岛优香 | 荒野求生21天去码版网站 | 人人妻人人澡人人爽精品欧美一区 | 午夜视频福利在线观看 | 成人在线中文字幕 | 欧美性大战久久久久久 | 日本人六九视频 | 玩弄人妻少妇500系列 | 成人福利视频在线 | 落日余晖 | 男女啪啪在线观看 | 成人综合在线观看 | 免费做a爰片77777 | 污网址在线观看 | 国产人妻精品一区二区三区不卡 | 老外毛片| 美女国产一区 | 亚洲AV无码精品色毛片浪潮 | 蜜臀av在线播放 | 亚洲网站一区 | 午夜影院色| 久久精品成人 | www噜噜噜 | 操校花视频 | 久久久久久久国产精品毛片 | 久久r精品 | 亚洲爽片| 亚洲逼图 | 放荡闺蜜高h苏桃情事h | 欧美综合亚洲 | 一女三黑人理论片在线 | 在线免费成人 | 中文字幕 日韩有码 | 99国产在线 | 久久久夜色精品亚洲 | 日本黄色大片在线观看 | 麻豆亚洲av熟女国产一区二 | 动漫毛片 | 五月av在线 | 亚洲12p| 久久综合色视频 | 色播五月婷婷 | 四虎黄网| 欧美xxxx黑人| 亚洲不卡在线视频 | 精品国产一区二区三区噜噜噜 | 国产精品久久久久久久久久久久 | 亚洲国产精品久久久久久 | 国产精品视频入口 | 日本在线视频一区二区 |