android框架_窗口管理WindowManagerGlobal与窗口服务WindowManagerService的分析_008

一、WindowManagerService(WMS)与WindowManagerGlobal之间的关系:

1、在每个Android应用中,都存在一个唯一的WindowManagerGlobal对象,这个对象中包含了能和WMS进行双向Binder通信的通道。如上图所示;

 

public class WindowManagerService extends IWindowManager.Stub
        implements Watchdog.Monitor, WindowManagerPolicy.WindowManagerFuncs {
    static final String TAG = "WindowManager";
    static boolean DEBUG = false;
    static boolean DEBUG_ADD_REMOVE = false;
public interface WindowManagerPolicy {
    // Policy flags.  These flags are also defined in frameworks/base/include/ui/Input.h.
    public final static int FLAG_WAKE = 0x00000001;
    public final static int FLAG_VIRTUAL = 0x00000002;

    public final static int FLAG_INJECTED = 0x01000000;

 

2、WindowManagerService服务继承接口IWindowManager.Stub,实现看门狗接口Watchdog.Monitor, 和WindowManagerPolicy接口中的内部接口WindowManagerPolicy.WindowManagerFuncs,这个暂时还不知道是做什么用??,以下分析这个接口类有哪些类实现了该类:WindowManagerPolicy;

 

public class PhoneWindowManager implements WindowManagerPolicy {
    static final String TAG = "WindowManager";
    /// M: runtime switch debug flags @{
    static boolean DEBUG = false;
    static boolean localLOGV = false;

3、PhoneWindowManager实现了WindowManagerPolicy接口;继续分析WindowManagerPolicy中的内部接口WindowState的实现类;

 

final class WindowState implements WindowManagerPolicy.WindowState {
    static final String TAG = "WindowState";

    final WindowManagerService mService;
    final WindowManagerPolicy mPolicy;

4、WindowState的官网解释:A window in the window manager;也就是这个类就是一个窗口;

 

public final class WindowManagerGlobal {
    private static final String TAG = "WindowManager";
    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>();
    private final ArraySet<View> mDyingViews = new ArraySet<View>();

    private Runnable mSystemPropertyUpdater;

    private WindowManagerGlobal() {
    }

    public static void initialize() {
        getWindowManagerService();
    }

    public static WindowManagerGlobal getInstance() {
        synchronized (WindowManagerGlobal.class) {
            if (sDefaultWindowManager == null) {
                sDefaultWindowManager = new WindowManagerGlobal();
            }
            return sDefaultWindowManager;
        }
    }

二、我们先从这个类代码量最小的类开始分析:WindowManagerGlobal.java

1、从上面贴出的代码来看,这个类是一个全局静态的单例类;

 

    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;
        }
    }

2、变量sWindowManagerService就是窗口服务WindowManagerService的引用类;循环调用getWindowManagerService()函数来获取WindowManagerService服务的引用类,直到WindowManagerService服务开启为止,因为服务器实现了一个叫做这样的一个Binder的接口类:IWindowManager; IWindowManager 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;
        }
    }

3、通过getWindowSession函数获取接口IWindowSession的变量;通过IWindowManager.openSession函数获取;稍后分析:

Session.java服务类,因为这个继承了IWindowSession.Stub;

 

    public static IWindowSession peekWindowSession() {
        synchronized (WindowManagerGlobal.class) {
            return sWindowSession;
        }
    }

4、通过peekWindowSession()获取已经存在的sWindowSession对象;

    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>();

5、这三个集合,保存了应用中所有顶层View相关信息。

mViews:保存的是所有顶层View的对象,(实际上是DecorView对象)。

mRoots:保存的是和顶层View关联的ViewRootImpl对象。

mParams保存的是创建顶层View的layout参数;

 

    public String[] getViewRootNames() {
        synchronized (mLock) {
            final int numRoots = mRoots.size();
            String[] mViewRoots = new String[numRoots];
            for (int i = 0; i < numRoots; ++i) {
                mViewRoots[i] = getWindowName(mRoots.get(i));
            }
            return mViewRoots;
        }
    }

    public View getRootView(String name) {
        synchronized (mLock) {
            for (int i = mRoots.size() - 1; i >= 0; --i) {
                final ViewRootImpl root = mRoots.get(i);
                if (name.equals(getWindowName(root))) return root.getView();
            }
        }

        return null;
    }

6、getViewRootNames函数是获取根视图的名称;getRootView函数是通过跟视图名称获取根视图view

    public void addView(View view, ViewGroup.LayoutParams params,
            Display display, Window parentWindow) {
        ......(具体见代码类)
            mViews.add(view);
            mRoots.add(root);
            mParams.add(wparams);
        ......
    }

    public void updateViewLayout(View view, ViewGroup.LayoutParams params) {
       ......
        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) {
        ......
        synchronized (mLock) {
            int index = findViewLocked(view, true);
            View curView = mRoots.get(index).getView();
            removeViewLocked(index, immediate);
            if (curView == view) {
                return;
            }
        }
    }

7、函数addView、updateViewLayout、removeView都是操作视图,与三个集合有关;

8、其他的方法比较简单,不做具体分析了;

总结:此类主要是获取全局变量、三个视图集合、窗口服务的接口引用对象;

 

三、分析Session.java服务类;

1、这个类位于包:com.android.server.wm中,在WindowManagerGlobal中通过getWindowSession函数获取,随后通过窗口服务类WindowManagerService.openSession()获取,openSession中new Session()对象,然后直接返回;

/**
 * This class represents an active client session.  There is generally one
 * Session object per process that is interacting with the window manager.
 */
final class Session extends IWindowSession.Stub
        implements IBinder.DeathRecipient {
    final WindowManagerService mService;
    final IWindowSessionCallback mCallback;
    final IInputMethodClient mClient;
    final IInputContext mInputContext;
    final int mUid;
    final int mPid;
    final String mStringName;
    SurfaceSession mSurfaceSession;
    int mNumWindow = 0;
    boolean mClientDead = false;
    float mLastReportedAnimatorScale;

    public Session(WindowManagerService service, IWindowSessionCallback callback,
            IInputMethodClient client, IInputContext inputContext) {

 

2、这个Session需要四个参数,第一个参数:调用this;第二个参数:new IWindowSessionCallback.Stub();第三个参数:

 

imm.getClient();第四个参数:imm.getInputContext();这里的imm就是InputMethodManager.getInstance()单例;

3、一个进程中有一个Session与WindowManager进行交互;

未完待续;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

 

四、应用中的Window对象;

public class Activity extends ContextThemeWrapper
        implements LayoutInflater.Factory2,
        Window.Callback, KeyEvent.Callback,
        OnCreateContextMenuListener, ComponentCallbacks2,
        Window.OnWindowDismissedCallback {
        ......
    private Window mWindow;

    private WindowManager mWindowManager;

1、每一个Activity中都有一个类型为Window的成员变量mWindow,Window对象在应用进程中代表一个窗口,这是一块矩形的图像绘制区域。WindowManagerService不关系各种View,只管理和调度Window对象,Activity的View树不管有多么复杂,最后输出的也只是一张由各个View合成的图像而已;

/**
 * Abstract base class for a top-level window look and behavior policy.  An
 * instance of this class should be used as the top-level view added to the
 * window manager. It provides standard UI policies such as a background, title
 * area, default key processing, etc.
 *
 * <p>The only existing implementation of this abstract class is
 * android.policy.PhoneWindow, which you should instantiate when needing a
 * Window.  Eventually that class will be refactored and a factory method
 * added for creating Window instances without knowing about a particular
 * implementation.
 */
public abstract class Window {
    /** Flag for the "options panel" feature.  This is enabled by default. */
    public static final int FEATURE_OPTIONS_PANEL = 0;

 

2、Window是一个抽象类,mWindow = PolicyManager.makeNewWindow(this)-->>sPolicy.makeNewWindow(context)

 

-->>new PhoneWindow(context); PhoneWindow继承Window抽象接口;

 

五、应用中的WindowManager对象;

1、在应用进程中,WindowManager对象用于和WindowManagerService通信,而在Activity中的成员变量有一个也是这种类型的对象:mWindowManager;它也是一个接口;继承ViewManager;因此可以肯定是mWindowManager引用了WindowManager的某个实现类的对象。接下来看mWindowManager的初始化操作;在Activity中

    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) {
        attachBaseContext(context);

        mFragments.attachActivity(this, mContainer, null);

        mWindow = PolicyManager.makeNewWindow(this);
        ........
        mWindowManager = mWindow.getWindowManager();
        mCurrentConfig = config;
    }

2、通过mWindow.getWindowManager()获取mWindowManager;而mWindow的实例是PhoneWindow,它的代码:

    public WindowManager getWindowManager() {
        return this.mWindowManager;
    }
this.mWindowManager = ((WindowManagerImpl)wm).createLocalWindowManager(this)

3、从代码中可以看出,WindowManager的实现类是WindowManagerImpl;看看它的定义:

public final class WindowManagerImpl implements WindowManager {
    private final WindowManagerGlobal mGlobal = WindowManagerGlobal.getInstance();
    private final Display mDisplay;
    private final Window mParentWindow;

    private IBinder mDefaultToken;

    public WindowManagerImpl(Display display) {
        this(display, null);
    }

    private WindowManagerImpl(Display display, Window parentWindow) {
        mDisplay = display;
        mParentWindow = parentWindow;
    }

    public WindowManagerImpl createLocalWindowManager(Window parentWindow) {
        return new WindowManagerImpl(mDisplay, parentWindow);
    }

    public WindowManagerImpl createPresentationWindowManager(Display display) {
        return new WindowManagerImpl(display, mParentWindow);
    }

4、拥有一个WindowManagerGlobal的对象,从WindowManagerImpl的代码中可以看出;类中的各种方法的实现只是在转调

WindowManagerGlobal类的方法,由此可见一个应用中的所有Activity都是通过这个进程内唯一的WindowManagerGlobal对象和

WMS通信。

Activity中WindowManager的继承关系图如下:

 

六、应用和WMS之间的联系之一ViewRootImp类;

/**
 * The top of a view hierarchy, implementing the needed protocol between View
 * and the WindowManager.  This is for the most part an internal implementation
 * detail of {@link WindowManagerGlobal}.
 *
 * {@hide}
 */
@SuppressWarnings({"EmptyCatchBlock", "PointlessBooleanExpression"})
public final class ViewRootImpl implements ViewParent,
        View.AttachInfo.Callbacks, HardwareRenderer.HardwareDrawCallbacks {
    private static final String TAG = "ViewRootImpl";
    /** M: Let DEBUG flags writable and add input event debug flag. @{ */
    private static final boolean IS_ENG_BUILD = "eng".equals(Build.TYPE);
    private static final boolean DEBUG_DEFAULT = IS_ENG_BUILD;
    private static boolean DBG = false; 
    .......
    final Context mContext;
    final IWindowSession mWindowSession;
    final Display mDisplay;
    final DisplayManager mDisplayManager;
    final String mBasePackageName;
    .......

1、可以看出ViewRootImpl是一个实实在在的类,继承ViewParent;同时也定义了几个与WMS有关系的变量;初始化如下:

   public ViewRootImpl(Context context, Display display) {
        mWindowSession = WindowManagerGlobal.getWindowSession();
        mDisplay = display;
        .......
        mWindow = new W(this);
        .......
        mAttachInfo = new View.AttachInfo(mWindowSession, mWindow, display, this, mHandler, this);
        .......
        mDisplayManager = (DisplayManager)context.getSystemService(Context.DISPLAY_SERVICE);
        loadSystemProperties();
        .......
    }

2、mWindowSession变量的类型就是IWindowSession;从WindowManagerGlobal单例中获取;getWindowSession函数上面分析过,这里就不在分析了;

3、只是说明一点:一个用户进程中所有ViewRootImpl对象中的mWindowSession都引用的是相同的对象。它就是应用中建立的一条通往WMS的Binder通道。下面继续分析从WMS到应用的Binder通道是如何建立的???

4、Activity启动时,会调用到ActivityThread的handleResumeActivity()方法,

    final void handleResumeActivity(IBinder token,
            boolean clearHide, boolean isForward, boolean reallyResume) {
    ......
    r.activity.makeVisible()
    ......
    }

5、Activity类中的makeVisible()

    void makeVisible() {
        if (!mWindowAdded) {
            ViewManager wm = getWindowManager();
            wm.addView(mDecor, getWindow().getAttributes());
            mWindowAdded = true;
        }
        /// M: BMW @{
        MultiWindowProxy mMultiWindowProxy = MultiWindowProxy.getInstance();            
        if (MultiWindowProxy.isFeatureSupport() && mMultiWindowProxy != null) {   
            mMultiWindowProxy.setFloatDecorVisibility(mToken, View.VISIBLE);
        } 
        /// @}
        mDecor.setVisibility(View.VISIBLE);
    }

6、makeVisible()方法,又调用了WindowManager的addView()方法,参数是这个Activity的顶层View对象mDecor。这里实际上就是调用了WindowManagerGlobal的addView方法,addView上面已经分析;

    public void addView(View view, ViewGroup.LayoutParams params,
            Display display, Window parentWindow) {
        .........
            root = new ViewRootImpl(view.getContext(), display);

            view.setLayoutParams(wparams);

            mViews.add(view);
            mRoots.add(root);
            mParams.add(wparams);
        .........
            root.setView(view, wparams, panelParentView);
        .........
    }

7、addView()方法最重要的是创建一个ViewRootImpl对象,并通过setView()方法把它和顶层的View对象关联在了一起;

    /**
     * We have one child
     */
    public void setView(View view, WindowManager.LayoutParams attrs, View panelParentView) {
        synchronized (this) {
            if (mView == null) {
                mView = view;
								........
                try {
                    mOrigWindowType = mWindowAttributes.type;
                    mAttachInfo.mRecomputeGlobalAttributes = true;
                    collectViewAttributes();
                    res = mWindowSession.addToDisplay(mWindow, mSeq, mWindowAttributes,
                            getHostVisibility(), mDisplay.getDisplayId(),
                            mAttachInfo.mContentInsets, mAttachInfo.mStableInsets, mInputChannel);
                } catch (RemoteException e) {
               ........   
    }

8、这个setView()方法中的有一个判断,会检测mView的值,ViewRootImpl对象和顶层View之间的关联只能执行一次。更重要的是此方法调用了Session的addToDisplay()方法。这个方法的第一个参数是mWindow变量,它是类W的实例对象,在ViewRootImpl类的构造方法中创建的。W是ViewRootImpl的嵌入类,定义如下:

    static class W extends IWindow.Stub {
        private final WeakReference<ViewRootImpl> mViewAncestor;
        private final IWindowSession mWindowSession;

        W(ViewRootImpl viewAncestor) {
            mViewAncestor = new WeakReference<ViewRootImpl>(viewAncestor);
            mWindowSession = viewAncestor.mWindowSession;
        }

 

9、W是一个Binder服务类,通过addToDisplay()方法将它的实例对象传递到WMS。W在WMS中的引用对象的类型是IWindow,

 

WMS保存了应用中每个顶层窗口的IWindow对象。

 

 

七、WMS中建立和应用的联系;

1、在WMS中,WindowState对象代表一个窗口,WindowState中定义了大量的成员变量来表示窗口信息,先看看下面的两个变量:

/**
 * A window in the window manager.
 */
final class WindowState implements WindowManagerPolicy.WindowState {
    static final String TAG = "WindowState";

    final WindowManagerService mService;
    final WindowManagerPolicy mPolicy;
    final Context mContext;
    final Session mSession;
    final IWindow mClient;
    final int mAppOp;
    // UserId and appId of the owner. Don't display windows of non-current user.
    final int mOwnerUid;
    final IWindowId mWindowId;
    WindowToken mToken;
    WindowToken mRootToken;
    AppWindowToken mAppToken;
    AppWindowToken mTargetAppToken;

2、其中mClient是客户进程中的Binder对象W的引用对象,而mSession是WMS中和为客户进程创建的Binder服务对象,mSession的类型是Session.

final class Session extends IWindowSession.Stub
        implements IBinder.DeathRecipient {
    final WindowManagerService mService;
    final IWindowSessionCallback mCallback;
    final IInputMethodClient mClient;
    final IInputContext mInputContext;
    .......
    SurfaceSession mSurfaceSession;
    .......
    }

 

3、Session类从IWindowSession.Stub派生,很明显是通过AIDL生成的BInder架构。这个类的作用是把来自用户进程的调用转换成调用WMS的接口。上面的Session接口方法addToDisplay(),实际上转调了WMS的addWindow()方法:

 

    @Override
    public int addToDisplay(IWindow window, int seq, WindowManager.LayoutParams attrs,
            int viewVisibility, int displayId, Rect outContentInsets, Rect outStableInsets,
            InputChannel outInputChannel) {
        return mService.addWindow(this, window, seq, attrs, viewVisibility, displayId,
                outContentInsets, outStableInsets, outInputChannel);
    }

 

    public int addWindow(Session session, IWindow client, int seq,
            WindowManager.LayoutParams attrs, int viewVisibility, int displayId,
            Rect outContentInsets, Rect outStableInsets, InputChannel outInputChannel) {
           ......
        synchronized(mWindowMap) {
           ......
            if (mWindowMap.containsKey(client.asBinder())) {
                Slog.w(TAG, "Window " + client + " is already added");
                return WindowManagerGlobal.ADD_DUPLICATE_ADD;
            }
           ......
            win = new WindowState(this, session, client, token,
                    attachedWindow, appOp[0], seq, attrs, viewVisibility, displayContent);
           ......
            win.attach();
            mWindowMap.put(client.asBinder(), win);
            ......

        return res;
    }

4、可以看到addWindow()方法中创建了WindowState对象,并将它加入到了mWindowMap列表中。mWindowMap保存了系统中所有的顶层窗口信息。

 

5、理解DecorView类;

PhoneWindow类中的成员变量mDecor的类型是DecorView,当调用setContentView方法时,如果mDecor对象还没有创建出来,则会调用installDecor()方法来创建Activity中的DecorView和其他的框架视图View,如:ActionBar:

    private void installDecor() {
        if (mDecor == null) {
            mDecor = generateDecor();
            mDecor.setDescendantFocusability(ViewGroup.FOCUS_AFTER_DESCENDANTS);
            mDecor.setIsRootNamespace(true);
            if (!mInvalidatePanelMenuPosted && mInvalidatePanelMenuFeatures != 0) {
                mDecor.postOnAnimation(mInvalidatePanelMenuRunnable);
            }
        }
        if (mContentParent == null) {
            mContentParent = generateLayout(mDecor);

            // Set up decor part of UI to ignore fitsSystemWindows if appropriate.
            mDecor.makeOptionalFitsSystemWindows();

6、installDecor()方法的主要功能是创建DecorView对象和它的下级Layout,如果Activity需要ActionBar,则创建相关的对象,当这个方法执行完成后,Activity的框架视图View就全部创建出来。

    private final class DecorView extends FrameLayout implements RootViewSurfaceTaker {

        /* package */int mDefaultOpacity = PixelFormat.OPAQUE;

        /** The feature ID of the panel, or -1 if this is the application's DecorView */
        private final int mFeatureId;

7、DecorView是定义在PhoneWindow.java中的,也是它的一个嵌入类:同时也是Activity中视图View树根视图;

 

 

八、分析WMS类;

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值