[ContextImpl](https://github.com/ziv-zh/platform_frameworks_base/blob/master/core/java/android/app/ContextImpl.java )java
[ActivityThread] (https://github.com/ziv-zh/platform_frameworks_base/blob/master/core/java/android/app/ContextImpl.java )android
[IBinder](https://github.com/ziv-zh/platform_frameworks_base/blob/master/core/java/android/os/IBinder.java ) binder 服務端(Stub)要實現的git
[Binder](https://github.com/ziv-zh/platform_frameworks_base/blob/master/core/java/android/os/Binder.java )默認的 binder 服務端實現github
[IInterface](https://github.com/ziv-zh/platform_frameworks_base/blob/master/core/java/android/os/IInterface.java )binder 客戶端(proxy)要實現的,通常 aidl 自動生成session
token 都是 IBinder 對象,用於 IPC ;app
1,Activity(和 Window,若是 window 對象關聯了一個 activity 的話) 中的 token 是由 AmS 建立的 ActivityRecord,用於 activity 通知 AmS 狀態變化;ide
2,ViewRoot 的 W 對象 mWindow,是有 ViewRoot 建立的,傳遞給 WmS,用於 WmS 通知 ViewRoot 狀態變化:this
WmS --> mWindow(Binder) --> mHandler(ViewRootHandler), 移步下面 " ViewRootImpl 的 mWindow 是如何傳遞給 WmS 的"spa
3,各類 XXXManager(好比WindowManager、ActivityManager)是一種 service 的封裝,內部有對應service 的 Binder 對象;rest
[IWindow.aidl]: https://github.com/android/platform_frameworks_base/blob/master/core/java/android/view/IWindow.aidl API back to a client window that the Window Manager uses to inform it of interesting things happening.
[IWindowSession.aidl] https://github.com/android/platform_frameworks_base/blob/master/core/java/android/view/IWindow.aidl System private per-application interface to the window manager.
1,Activity 建立完會建立 Window,並給 window 設置 contentView,這個過程當中會建立 decorView;
2,Activity 準備好通知 AmS,AmS 判斷狀態後最終調用 Activity 的 makeVisible(..),此方法中調用 WindowManager(會調用WindowManagerGlobal的 addView) 的 addView(..)展現 view;
3,在 addView 方法中進行檢查並並建立 ViewRootImpl 對象,最終調用 ViewRootImpl 的 setView 方法,在此方法中會把 mWindow 這個 binder 經過 mWindowSession 註冊給 WmS;
ps: mWindowSession 是 WmS 提供的一個 Binder 對象(因此使用時要處理 RemoteException),從 WindowManagerGlobal 的方法中能夠看出;
ps: mAttachInfo 是在 ViewRootImpl 的構造方法中建立的,並在 setView 方法中設置一些其餘的變量(好比 mRootView),
而且在 ViewRootImpl 的 'void dispatchAttachedToWindow(AttachInfo info, int visibility)' 方法把 mAttatchedInfo 傳遞給 view;
ViewRootImpl.java:
final IWindowSession mWindowSession; ... final W mWindow; ... public void setView(View view, WindowManager.LayoutParams attrs, View panelParentView) { synchronized (this) { ... try { mOrigWindowType = mWindowAttributes.type; mAttachInfo.mRecomputeGlobalAttributes = true; collectViewAttributes(); res = mWindowSession.addToDisplay(mWindow, mSeq, mWindowAttributes, getHostVisibility(), mDisplay.getDisplayId(), mAttachInfo.mContentInsets, mAttachInfo.mStableInsets, mAttachInfo.mOutsets, mInputChannel); } catch (RemoteException e) { ... }
WindowManagerGlobal.java:
... public static IWindowManager getWindowManagerService() { synchronized (WindowManagerGlobal.class) { if (sWindowManagerService == null) { sWindowManagerService = IWindowManager.Stub.asInterface( ServiceManager.getService("window")); try { sWindowManagerService = getWindowManagerService(); ValueAnimator.setDurationScale(sWindowManagerService.getCurrentAnimatorScale()); } catch (RemoteException e) { Log.e(TAG, "Failed to get WindowManagerService, cannot set animator scale", e); } } return sWindowManagerService; } } public static IWindowSession getWindowSession() { synchronized (WindowManagerGlobal.class) { if (sWindowSession == null) { try { InputMethodManager imm = InputMethodManager.getInstance(); IWindowManager windowManager = getWindowManagerService(); sWindowSession = windowManager.openSession( new IWindowSessionCallback.Stub() { @Override public void onAnimatorScaleChanged(float scale) { ValueAnimator.setDurationScale(scale); } }, imm.getClient(), imm.getInputContext()); } catch (RemoteException e) { Log.e(TAG, "Failed to open window session", e); } } return sWindowSession; } } public void addView(View view, ViewGroup.LayoutParams params, Display display, Window parentWindow) { ... 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); } } } root = new ViewRootImpl(view.getContext(), display); view.setLayoutParams(wparams); mViews.add(view); mRoots.add(root); mParams.add(wparams); } // do this last because it fires off messages to start doing things try { 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; } } ...