<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                #### 8.3.1 Activity的Window創建過程 要分析Activity中的Window的創建過程就必須了解Activity的啟動過程,詳細的過程會在第9章進行介紹,這里先大概了解即可。Activity的啟動過程很復雜,最終會由ActivityThread中的performLaunchActivity()來完成整個啟動過程,在這個方法內部會通過類加載器創建Activity的實例對象,并調用其attach方法為其關聯運行過程中所依賴的一系列上下文環境變量,代碼如下所示。 java.lang.ClassLoader cl = r.packageInfo.getClassLoader(); activity = mInstrumentation.newActivity( cl, component.getClassName(), r.intent); ... if (activity ! = null) { Context appContext = createBaseContextForActivity(r, activity); CharSequence title = r.activityInfo.loadLabel(appContext.getPackage- Manager()); Configuration config = new Configuration(mCompatConfiguration); if (DEBUG_CONFIGURATION) Slog.v(TAG, "Launching activity " + r.activityInfo.name + " with config " + config); activity.attach(appContext, this, getInstrumentation(), r.token, r.ident, app, r.intent, r.activityInfo, title, r.parent, r.embeddedID, r.lastNonConfigurationInstances, config, r.voiceInteractor); ... } 在Activity的attach方法里,系統會創建Activity所屬的Window對象并為其設置回調接口,Window對象的創建是通過PolicyManager的makeNewWindow方法實現的。由于Activity實現了Window的Callback接口,因此當Window接收到外界的狀態改變時就會回調Activity的方法。Callback接口中的方法很多,但是有幾個卻是我們都非常熟悉的,比如onAttachedToWindow、onDetachedFromWindow、dispatchTouchEvent,等等,代碼如下所示。 mWindow = PolicyManager.makeNewWindow(this); mWindow.setCallback(this); mWindow.setOnWindowDismissedCallback(this); mWindow.getLayoutInflater().setPrivateFactory(this); if (info.softInputMode ! = WindowManager.LayoutParams.SOFT_INPUT_STATE_ UNSPECIFIED) { mWindow.setSoftInputMode(info.softInputMode); } if (info.uiOptions ! = 0) { mWindow.setUiOptions(info.uiOptions); } 從上面的分析可以看出,Activity的Window是通過PolicyManager的一個工廠方法來創建的,但是從PolicyManager的類名可以看出,它不是一個普通的類,它是一個策略類。PolicyManager中實現的幾個工廠方法全部在策略接口IPolicy中聲明了,IPolicy的定義如下: public interface IPolicy { public Window makeNewWindow(Context context); public LayoutInflater makeNewLayoutInflater(Context context); public WindowManagerPolicy makeNewWindowManager(); public FallbackEventHandler makeNewFallbackEventHandler(Context context); } 在實際的調用中,PolicyManager的真正實現是Policy類,Policy類中的makeNewWindow方法的實現如下,由此可以發現,Window的具體實現的確是PhoneWindow。 public Window makeNewWindow(Context context) { return new PhoneWindow(context); } 關于策略類PolicyManager是如何關聯到Policy上面的,這個無法從源碼中的調用關系來得出,這里猜測可能是由編譯環節動態控制的。到這里Window已經創建完成了,下面分析Activity的視圖是怎么附屬在Window上的。由于Activity的視圖由setContentView方法提供,我們只需要看setContentView方法的實現即可。 public void setContentView(int layoutResID) { getWindow().setContentView(layoutResID); initWindowDecorActionBar(); } 從Activity的setContentView的實現可以看出,Activity將具體實現交給了Window處理,而Window的具體實現是PhoneWindow,所以只需要看PhoneWindow的相關邏輯即可。PhoneWindow的setContentView方法大致遵循如下幾個步驟。 * 1.如果沒有DecorView,那么就創建它 DecorView是一個FrameLayout,在第4章已經做了初步的介紹,這里再簡單說一下。DecorView是Activity中的頂級View,一般來說它的內部包含標題欄和內部欄,但是這個會隨著主題的變換而發生改變。不管怎么樣,內容欄是一定要存在的,并且內容來具體固定的id,那就是“content”,它的完整id是android.R.id.content。DecorView的創建過程由installDecor方法來完成,在方法內部會通過generateDecor方法來直接創建DecorView,這個時候DecorView還只是一個空白的FrameLayout: protected DecorView generateDecor() { return new DecorView(getContext(), -1); } 為了初始化DecorView的結構,PhoneWindow還需要通過generateLayout方法來加載具體的布局文件到DecorView中,具體的布局文件和系統版本以及主題有關,這個過程如下所示。 View in = mLayoutInflater.inflate(layoutResource, null); decor.addView(in, new ViewGroup.LayoutParams(MATCH_PARENT, MATCH_PARENT)); mContentRoot = (ViewGroup) in; ViewGroup contentParent = (ViewGroup)findViewById(ID_ANDROID_CONTENT); 其中ID_ANDROID_CONTENT的定義如下,這個id所對應的ViewGroup就是mContentParent: public static final int ID_ANDROID_CONTENT = com.android.internal.R.id. content * 2.將View添加到DecorView的mContentParent中 這個過程就比較簡單了,由于在步驟1中已經創建并初始化了DecorView,因此這一步直接將Activity的視圖添加到DecorView的mContentParent中即可:mLayoutInflater. inflate(layoutResID, mContentParent)。到此為止,Activity的布局文件已經添加到DecorView里面了,由此可以理解Activity的setContentView這個方法的來歷了。不知道讀者是否曾經懷疑過:為什么不叫setView呢?它明明是給Activity設置視圖的啊!從這里來看,它的確不適合叫setView,因為Activity的布局文件只是被添加到DecorView的mContentParent中,因此叫setContentView更加準確。 * 3.回調Activity的onContentChanged方法通知Activity視圖已經發生改變 這個過程就更簡單了,由于Activity實現了Window的Callback接口,這里表示Activity的布局文件已經被添加到DecorView的mContentParent中了,于是需要通知Activity,使其可以做相應的處理。Activity的onContentChanged方法是個空實現,我們可以在子Activity中處理這個回調。這個過程的代碼如下所示。 final Callback cb = getCallback(); if (cb ! = null && ! isDestroyed()) { cb.onContentChanged(); } 經過了上面的三個步驟,到這里為止DecorView已經被創建并初始化完畢,Activity的布局文件也已經成功添加到了DecorView的mContentParent中,但是這個時候DecorView還沒有被WindowManager正式添加到Window中。這里需要正確理解Window的概念,Window更多表示的是一種抽象的功能集合,雖然說早在Activity的attach方法中Window就已經被創建了,但是這個時候由于DecorView并沒有被WindowManager識別,所以這個時候的Window無法提供具體功能,因為它還無法接收外界的輸入信息。在ActivityThread的handleResumeActivity方法中,首先會調用Activity的onResume方法,接著會調用Activity的makeVisible(),正是在makeVisible方法中,DecorView真正地完成了添加和顯示這兩個過程,到這里Activity的視圖才能被用戶看到,如下所示。 void makeVisible() { if (! mWindowAdded) { ViewManager wm = getWindowManager(); wm.addView(mDecor, getWindow().getAttributes()); mWindowAdded = true; } mDecor.setVisibility(View.VISIBLE); } 到這里,Activity中的Window的創建過程已經分析完了,讀者對整個過程是不是有了更進一步的理解了呢?
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看