標籤:one surface wro window 介面 mha ceo surf ane
部落格首頁:http://www.cnblogs.com/kezhuang/p/
關於Activity的contentView的構建過程,我在我的部落格中已經分析過了,不瞭解的可以去看一下
《[Android FrameWork 6.0源碼學習] Window視窗類別分析》
本章部落格是接著上邊那篇部落格分析,目的是為了引出分析ViewRootImpl這個類。現在只是分析完了Window和ActivityThread的調用過程
從ActivityThread到WindowManager再到ViewRootImpl這塊還屬於空白部分,所以要補這篇部落格
在上篇部落格的末尾提到最後是由WindowManager的addView來請求顯示介面,那麼我們接著分析
WindowManager這是一個介面,他繼承了ViewManager這個介面,所以具有管理View的能力
WindowManager這個執行個體是通過 Activity.getWindowManager 方法擷取的,我們先找到他的執行個體,在逐漸去看addView函數
public WindowManager getWindowManager() { return mWindowManager; }
Activity中是這樣定義的該函數,返回了mWindowManager對像,接下來找一下賦值mWindowManager對象的地方
final void attach(Context context, ActivityThread aThread, Instrumentation instr, IBinder token, int ident, Application application, Intent intent, ActivityInfo info, CharSequence title, Activity parent, String id, NonConfigurationInstances lastNonConfigurationInstances, Configuration config, String referrer, IVoiceInteractor voiceInteractor) { mWindow = new PhoneWindow(this); mWindow.setCallback(this); mWindow.setOnWindowDismissedCallback(this); mWindow.getLayoutInflater().setPrivateFactory(this); mWindow.setWindowManager( (WindowManager)context.getSystemService(Context.WINDOW_SERVICE), mToken, mComponent.flattenToString(), (info.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0); if (mParent != null) { mWindow.setContainer(mParent.getWindow()); } mWindowManager = mWindow.getWindowManager(); }
我們看到在Activity初始化時候調用的attach方法中賦值了mWindowManager方法,但是這個值是從mWindow對象中擷取到的,我們進入看一下
public WindowManager getWindowManager() { return mWindowManager; }
在Window中也是這樣定義的,返回mWindowManager
public void setWindowManager(WindowManager wm, IBinder appToken, String appName, boolean hardwareAccelerated) { mAppToken = appToken; mAppName = appName; mHardwareAccelerated = hardwareAccelerated || SystemProperties.getBoolean(PROPERTY_HARDWARE_UI, false); if (wm == null) { wm = (WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE); } mWindowManager = ((WindowManagerImpl)wm).createLocalWindowManager(this); }
Window中的mWindowManager是在setWindowManager中建立而來,而這個setWindowManager其實是在Activity的attach方法中調用
可以看到其實就是用的系統服務WindowManager強轉成WindowManagerImpl之後又調用了createLocalWindowManager方法得到的對象
public WindowManagerImpl createLocalWindowManager(Window parentWindow) { return new WindowManagerImpl(mDisplay, parentWindow); }
這個方法也很簡單,就是new了一下WindowManagerImpl
OK了,到現在可以知道WindowManager的實作類別為WindowManagerImpl,那麼我們繼續分析它實現的addView方法
@Override public void addView(@NonNull View view, @NonNull ViewGroup.LayoutParams params) { applyDefaultToken(params); mGlobal.addView(view, params, mDisplay, mParentWindow); }
該方法定義在WindowManagerImpl中,mGlobal為WindowManagerGlobal對象,是一個系統單例對象
public void addView(View view, ViewGroup.LayoutParams params, Display display, Window parentWindow) { if (view == null) { throw new IllegalArgumentException("view must not be null"); } if (display == null) { throw new IllegalArgumentException("display must not be null"); } if (!(params instanceof WindowManager.LayoutParams)) { throw new IllegalArgumentException("Params must be WindowManager.LayoutParams"); } final WindowManager.LayoutParams wparams = (WindowManager.LayoutParams) params; if (parentWindow != null) { parentWindow.adjustLayoutParamsForSubWindow(wparams); } else { // If there‘s no parent, then hardware acceleration for this view is // set from the application‘s hardware acceleration setting. final Context context = view.getContext(); if (context != null && (context.getApplicationInfo().flags & ApplicationInfo.FLAG_HARDWARE_ACCELERATED) != 0) { wparams.flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED; } } ViewRootImpl root; View panelParentView = null; synchronized (mLock) { // Start watching for system property changes. if (mSystemPropertyUpdater == null) { mSystemPropertyUpdater = new Runnable() { @Override public void run() { synchronized (mLock) { for (int i = mRoots.size() - 1; i >= 0; --i) { mRoots.get(i).loadSystemProperties(); } } } }; SystemProperties.addChangeCallback(mSystemPropertyUpdater); } int index = findViewLocked(view, false); if (index >= 0) { if (mDyingViews.contains(view)) { // Don‘t wait for MSG_DIE to make it‘s way through root‘s queue. mRoots.get(index).doDie(); } else { throw new IllegalStateException("View " + view + " has already been added to the window manager."); } // The previous removeView() had not completed executing. Now it has. } // 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.size(); for (int i = 0; i < count; i++) { if (mRoots.get(i).mWindow.asBinder() == wparams.token) { panelParentView = mViews.get(i); } } } //建立了一個新的ViewRootImpl對象出來 root = new ViewRootImpl(view.getContext(), display); view.setLayoutParams(wparams); //為當前介面儲存ViewRootImpl和view還有添加的Layout參數 mViews.add(view); mRoots.add(root); mParams.add(wparams); } // do this last because it fires off messages to start doing things try { //調用ViewRootImpl中的setView方法,準備進行View的重繪流程,並且繪製到介面上 root.setView(view, wparams, panelParentView); } catch (RuntimeException e) { // BadTokenException or InvalidDisplayException, clean up. synchronized (mLock) { final int index = findViewLocked(view, false); if (index >= 0) { removeViewLocked(index, true); } } throw e; } }
這篇部落格到這就結束了,接下來我總結下上邊的流程
1.Activity初始化的時候建立了一個WindowManager對象(和系統的WindowManager服務還有點區別)
2.利用這個Activity專屬的WindowManager對象請求添加一個View到當前介面上
3.WindowManager找到自己的實作類別WindowManagerImpl,然後在委託給系統單例類WindowManagerGlobal處理
4.WindowManagerGlobal會建立一個ViewRootImpl對象出來
5.ViewRootImpl對象調用setView方法,然後進行介面重繪最後交給Surface進行介面展示
Ok了,很清晰的分析出了從WindowManager到ViewRootImpl的過程,接下來就可以分析ViewRootImpl.setView和ViewRootImpl的performTraversals方法了
[Android FrameWork 6.0源碼學習] View的重繪過程之WindowManager的addView方法