Android PhoneWindowManager WindowManagerGlobal WindowManagerImpl的作用和关系

来源:互联网 发布:怎么注册淘宝秒杀群 编辑:程序博客网 时间:2024/05/17 04:39

WindowManagerService作为Window和输入事件的管理中心,这个是很容易理解的,而IWindowManager 的proxy端就不那么好理解的了,和WindowManager有关的就有PhoneWindowManager、WindowManagerGlobal和WindowManagerImpl三个,下面我们来简单分析一下三者的作用和关系。


1.PhoneWindowManager

PhoneWindowManager实现WindowManagerPolicy接口,

This interface supplies all UI-specific behavior of the window manager. 

WindowManagerPolicy提供所有和UI有关的接口

public class WindowManagerService extends IWindowManager.Stub        implements Watchdog.Monitor, WindowManagerPolicy.WindowManagerFuncs {......final WindowManagerPolicy mPolicy = new PhoneWindowManager();......    private void initPolicy() {        UiThread.getHandler().runWithScissors(new Runnable() {            @Override            public void run() {                WindowManagerPolicyThread.set(Thread.currentThread(), Looper.myLooper());                mPolicy.init(mContext, WindowManagerService.this, WindowManagerService.this);                mAnimator.mAboveUniverseLayer = mPolicy.getAboveUniverseLayer()                        * TYPE_LAYER_MULTIPLIER                        + TYPE_LAYER_OFFSET;            }        }, 0);    }......private WindowManagerService(Context context, InputManagerService inputManager,            boolean haveInputMethods, boolean showBootMsgs, boolean onlyCore) {......LocalServices.addService(WindowManagerPolicy.class, mPolicy);}......}
PhoneWindowManager作为WindowManagerService的对象,主要用来管理和window有关的接口

2.WindowManagerGlobal

    private static WindowManagerGlobal sDefaultWindowManager;    private static IWindowManager sWindowManagerService;    private static IWindowSession sWindowSession;    private final Object mLock = new Object();    private final ArrayList<View> mViews = new ArrayList<View>();    private final ArrayList<ViewRootImpl> mRoots = new ArrayList<ViewRootImpl>();    private final ArrayList<WindowManager.LayoutParams> mParams =            new ArrayList<WindowManager.LayoutParams>();

WindowManagerGlobal主要用于管理ViewRoot、创建并提供IWindowManager的proxy实例。

    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 and we're running on L or above (or in the            // system context), assume we want hardware acceleration.            final Context context = view.getContext();            if (context != null                    && context.getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.LOLLIPOP) {                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;        }    }    public void updateViewLayout(View view, ViewGroup.LayoutParams params) {        if (view == null) {            throw new IllegalArgumentException("view must not be null");        }        if (!(params instanceof WindowManager.LayoutParams)) {            throw new IllegalArgumentException("Params must be WindowManager.LayoutParams");        }        final WindowManager.LayoutParams wparams = (WindowManager.LayoutParams)params;        view.setLayoutParams(wparams);        synchronized (mLock) {            int index = findViewLocked(view, true);            ViewRootImpl root = mRoots.get(index);            mParams.remove(index);            mParams.add(index, wparams);            root.setLayoutParams(wparams, false);        }    }    public void removeView(View view, boolean immediate) {        if (view == null) {            throw new IllegalArgumentException("view must not be null");        }        synchronized (mLock) {            int index = findViewLocked(view, true);            View curView = mRoots.get(index).getView();            removeViewLocked(index, immediate);            if (curView == view) {                return;            }            throw new IllegalStateException("Calling with view " + view                    + " but the ViewAncestor is attached to " + curView);        }    }

跟View有关的接口 比如addView、removeView、updateViewLayout等在WindowManagerGlobal实现。WindowManagerGlobal管理所有的View。

private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) {        // If we are getting ready to gc after going to the background, well        // we are back active so skip it.        unscheduleGcIdler();        mSomeActivitiesChanged = true;        if (r.profilerInfo != null) {            mProfiler.setProfiler(r.profilerInfo);            mProfiler.startProfiling();        }        // Make sure we are running with the most recent config.        handleConfigurationChanged(null, null);        if (localLOGV) Slog.v(            TAG, "Handling launch of " + r);        // Initialize before creating the activity        WindowManagerGlobal.initialize();......}
WindowManagerGlobal在ActivityThread中的handleLaunchActivity方法中初始化,也就是启动activity的时候。

3.WindowManagerImpl

public final class WindowManagerImpl implements WindowManager {    private final WindowManagerGlobal mGlobal = WindowManagerGlobal.getInstance();    private final Display mDisplay;    private final Window mParentWindow;    private IBinder mDefaultToken;
WindowManagerImpl是WindowManagerGlobal的代理类,另外还管理Dislay对象

        registerService(Context.WINDOW_SERVICE, WindowManager.class,                new CachedServiceFetcher<WindowManager>() {            @Override            public WindowManager createService(ContextImpl ctx) {                return new WindowManagerImpl(ctx);            }});

我们通过getSystemService(Context.WINDOW_SERVICE)获取到的是WindowManagerImpl对象,addView时,实际上都是WindowManagerGlobal在做事。


阅读全文
1 0
原创粉丝点击