WindowManagerService 分析

一 概述

WindowManagerService(WMS)根据字面意思理解就可知道是窗口管理服务,与AMS一样是framewrok层的核心服务;负责窗口的启动,添加,删除等;了解WMS首先来了解下Window的体系结构

1.1 Window体系图

WindowManagerService 分析_第1张图片

二 从WMS的启动分析

2.1 SystemService.startOtherServices

[—>SystemService.java]

private void startOtherServices() {
    ...
    // [见2.2]
    WindowManagerService wm = WindowManagerService.main(context, inputManager,
    mFactoryTestMode != FactoryTest.FACTORY_TEST_LOW_LEVEL,
    !mFirstBoot, mOnlyCore);

    wm.displayReady(); 
    ...
    wm.systemReady(); 
}

与ams一样,在system_service进程创建的时候会启动这些服务

2.2 WMS.main

[—>WindowManagerService.java]

public static WindowManagerService main(final Context context,
            final InputManagerService im,
            final boolean haveInputMethods, final boolean showBootMsgs,
            final boolean onlyCore) {
        final WindowManagerService[] holder = new WindowManagerService[1];
        DisplayThread.getHandler().runWithScissors(new Runnable() {
            @Override
            public void run() {
                //真正的创建wms,运行在"android.display"线程[见2.3]
                holder[0] = new WindowManagerService(context, im,
                        haveInputMethods, showBootMsgs, onlyCore);
            }
        }, 0);
        return holder[0];
    }

可见wms是运行在android.display线程中的

2.3 WindowManagerService

private WindowManagerService(Context context, InputManagerService inputManager, boolean haveInputMethods, boolean showBootMsgs, boolean onlyCore) {
    mContext = context;
    mHaveInputMethods = haveInputMethods;
    mAllowBootMessages = showBootMsgs;
    mOnlyCore = onlyCore;
    ...
    mInputManager = inputManager; 
    mDisplayManagerInternal = LocalServices.getService(DisplayManagerInternal.class);
    mDisplaySettings = new DisplaySettings();
    mDisplaySettings.readSettingsLocked();

    LocalServices.addService(WindowManagerPolicy.class, mPolicy);
    mPointerEventDispatcher = new PointerEventDispatcher(mInputManager.monitorInput(TAG));

    mFxSession = new SurfaceSession();
    mDisplayManager = (DisplayManager)context.getSystemService(Context.DISPLAY_SERVICE);
    mDisplays = mDisplayManager.getDisplays();

    for (Display display : mDisplays) {
        createDisplayContentLocked(display);
    }

    mKeyguardDisableHandler = new KeyguardDisableHandler(mContext, mPolicy);
    ...

    mAppTransition = new AppTransition(context, mH);
    mAppTransition.registerListenerLocked(mActivityManagerAppTransitionNotifier);
    mActivityManager = ActivityManagerNative.getDefault();
    ...
    mAnimator = new WindowAnimator(this);

    LocalServices.addService(WindowManagerInternal.class, new LocalService());
    //初始化策略[见2.4]
    initPolicy();

    Watchdog.getInstance().addMonitor(this);

    SurfaceControl.openTransaction();
    try {
        createWatermarkInTransaction();
        mFocusedStackFrame = new FocusedStackFrame(
                getDefaultDisplayContentLocked().getDisplay(), mFxSession);
    } finally {
        SurfaceControl.closeTransaction();
    }

    updateCircularDisplayMaskIfNeeded();
    showEmulatorDisplayOverlayIfNeeded();
}

2.4 WMS.initPolicy

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);
            }
        }, 0);
}

在android ui线程初始化完成后进行策略初始化

2.5 总结

在启动过程中一共有三个线程:system_server主线程,android.display线程,android.ui线程;

其中WMS.H.handleMessage运行在android.display线程。

三 从Activity角度分析WMS

3.1 ActivityThread.handleLaunchActivity

从startActivity的流程可以看出,AMS最终通过ApplicationThread调用了ActivityThread.handleLaunchActivity

[—>ActivityThread.java]

private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) {
        ......
        //[见3.1.1]
        WindowManagerGlobal.initialize();
        Activity a = performLaunchActivity(r, customIntent);
}

private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
        ......
        Activity activity = null;
        try {
            //通过反射创建activity
            java.lang.ClassLoader cl = r.packageInfo.getClassLoader();
            activity = mInstrumentation.newActivity(
                    cl, component.getClassName(), r.intent);
            StrictMode.incrementExpectedActivityCount(activity.getClass());
            r.intent.setExtrasClassLoader(cl);
            r.intent.prepareToEnterProcess();
            if (r.state != null) {
                r.state.setClassLoader(cl);
            }
        } catch (Exception e) {
            if (!mInstrumentation.onException(activity, e)) {
                throw new RuntimeException(
                    "Unable to instantiate activity " + component
                    + ": " + e.toString(), e);
            }
        }

        try {
            ......
            if (activity != null) {
               ......
               //activity绑定环境 [见3.2]
                activity.attach(appContext, this, getInstrumentation(), r.token,
                        r.ident, app, r.intent, r.activityInfo, title, r.parent,
                        r.embeddedID, r.lastNonConfigurationInstances, config,
                        r.referrer, r.voiceInteractor, window);
              ......
        } catch (Exception e) {
            if (!mInstrumentation.onException(activity, e)) {
                throw new RuntimeException(
                    "Unable to start activity " + component
                    + ": " + e.toString(), e);
            }
        }
        return activity;
    }

通过上面方法可以看出,Activity通过反射创建成功后进行环境的绑定,最后调用onCreate生命周期

3.1.1 WindowManagerGlobal.initialize

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

public static IWindowManager getWindowManagerService() {
    synchronized (WindowManagerGlobal.class) {
        if (sWindowManagerService == null) {
            //获取WMS的binder代理
            sWindowManagerService = IWindowManager.Stub.asInterface(
                    ServiceManager.getService("window"));
            sWindowManagerService = getWindowManagerService();
            ValueAnimator.setDurationScale(sWindowManagerService.getCurrentAnimatorScale());
        }
        return sWindowManagerService;
    }
}

可以看出,在进行activity创建之前通过WindowManagerGlobal初始化获取到了WMS的binder服务端的代表;

在后面我们可以看出来WindowManagerGlobal才是真正的对view进行操作的管理类,它是一个单例,管理着所有PhoneWind所承载的View;WindowMangerImpl只是一个代理类

3.2 Activity.attach

[—>Activity.java]

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,
            Window window) {
        attachBaseContext(context);
        mFragments.attachHost(null /*parent*/);
        //创建Window,Window只是一个抽象类,真正的实现类是PhoneWindow,这个是视图的view的载体
        mWindow = new PhoneWindow(this, window);
        mWindow.setWindowControllerCallback(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);
        }
       ......
       //设置Window管理器[见3.3]
        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();
        mCurrentConfig = config;
    }

初始化activity,为activity成员变量赋值:

mWindow:数据类型为Window,真正的实现类为PhoneWindow

mWindowManager:数据类型为WindowManagerImpl

mMainThread:当前线程的ActivityThread对象

mApplication:当前Activity所属的Application

mHandler:当前线程的Handler

mUiThread:当前Activity所在的主线程

mToken:远程ActivityRecord的appToken的代理 端

3.3 Window.setWindowManager

[—>Window.java]

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);
        }
        //创建Window管理类 [见3.4]
        mWindowManager = ((WindowManagerImpl)wm).createLocalWindowManager(this);
    }

3.4 WindowManagerImpl.createLocalWindowManager

[—>WindowManagerImpl.java]

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

从这可以看出PhoneWindow中的Window的管理类是WindowManagerImpl,其实它是相当于一个代理类;它的内部是通过WindowManagerGlobal这个单例来对View进行管理的

3.5 ActivityThread.handleResumeActivity

在AMS调用完ActivityThread.handleLaunchActivity后走完onCreate生命周期接下来就是调用handleResumeActivity,走onResume生命周期了

final void handleResumeActivity(IBinder token, boolean clearHide, boolean isForward, boolean reallyResume) {
    ...
    //执行到onResume方法
    ActivityClientRecord r = performResumeActivity(token, clearHide);
    if (r != null) {
        final Activity a = r.activity;
        boolean willBeVisible = !a.mStartedActivity;
        ...
        if (r.window == null && !a.mFinished && willBeVisible) {
            r.window = r.activity.getWindow();
            View decor = r.window.getDecorView();
            decor.setVisibility(View.INVISIBLE);
            ViewManager wm = a.getWindowManager();
            WindowManager.LayoutParams l = r.window.getAttributes();
            a.mDecor = decor;
            l.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
            l.softInputMode |= forwardBit;
            if (a.mVisibleFromClient) {
                a.mWindowAdded = true;
                wm.addView(decor, l);
            }

        }
        ...
        if (!r.activity.mFinished && willBeVisible
                && r.activity.mDecor != null && !r.hideForNow) {
            ...
            mNumVisibleActivities++;
            if (r.activity.mVisibleFromClient) {
                //添加视图[见3.6]
                r.activity.makeVisible(); 
            }
        }
        //resume完成
        if (reallyResume) {
              ActivityManagerNative.getDefault().activityResumed(token);
        }
    } else {
        ...
    }
}

方法中通过调用performResumeActivity来完成onResume生命周期的回调,makeVisible方法最终通过WMS服务操作View

3.6 Activity.makeVisible

[—>Activity.java]

void makeVisible() {
        if (!mWindowAdded) {
            //这里返回的ViewManager其实就是WindowManagerImpl [见3.3]
            ViewManager wm = getWindowManager();
            //[见3.6.1]
            wm.addView(mDecor, getWindow().getAttributes());
            mWindowAdded = true;
        }
        mDecor.setVisibility(View.VISIBLE);
    }
3.6.1 WindowManagerImpl.addView
public void addView(@NonNull View view, @NonNull ViewGroup.LayoutParams params) {
        applyDefaultToken(params);
        //[见3.6.2]
        mGlobal.addView(view, params, mContext.getDisplay(), mParentWindow);
    }
3.6.2 WindowManagerGlobal.addView
public void addView(View view, ViewGroup.LayoutParams params,
            Display display, Window parentWindow) {
        ......
        ViewRootImpl root;
        View panelParentView = null;
        ......
            //[见3.7]
            root = new ViewRootImpl(view.getContext(), display);

            view.setLayoutParams(wparams);

            mViews.add(view);
            mRoots.add(root);
            mParams.add(wparams);

        try {
            //[见3.7.3]
            root.setView(view, wparams, panelParentView);
        } catch (RuntimeException e) {
            synchronized (mLock) {
                final int index = findViewLocked(view, false);
                if (index >= 0) {
                    removeViewLocked(index, true);
                }
            }
            throw e;
        }
    }

WindowManagerGlobal类中几个重要的成员:

mViews:管理的所有View

mRoots:View所对应的ViewRootImpl

mParams:View所对应的LayoutParams

这三个成员变量都是大小始终保持相等的数组,这样有关联关系的View对象,ViewRoot和WindowManager.LayoutParams对象分别保存在数组mViews,mRoots,mParams的相同位置上,即mViews[i],mRoots[i],mParams[i]所描述的对象都是具有关联关系的。

3.7 ViewRootImpl

[—>ViewRootImpl.java]

public ViewRootImpl(Context context, Display display) {
    mContext = context;
    //获取IWindowSession的代理类 [见3.7.1]
    mWindowSession = WindowManagerGlobal.getWindowSession();
    mDisplay = display;
    mThread = Thread.currentThread(); //主线程
    mWindow = new W(this); 
    mChoreographer = Choreographer.getInstance();
    ...
}

初始化操作:

mWindowSession:WMS端的Session的代理 对象

mWindow:继承于IWindow.Stub的W对象

mChoreographer:绘制相关的对象

3.7.1 WindowManagerGlobal.getWindowSession

[—>WindowManagerGlobal.java]

public static IWindowSession getWindowSession() {
    synchronized (WindowManagerGlobal.class) {
        if (sWindowSession == null) {
            try {
                InputMethodManager imm = InputMethodManager.getInstance();
                //获取WMS的代理类
                IWindowManager windowManager = getWindowManagerService();
                //经过Binder调用,最终调用WMS[见3.7.2]
                sWindowSession = windowManager.openSession(
                        new IWindowSessionCallback.Stub() {...},
                        imm.getClient(), imm.getInputContext());
            } catch (RemoteException e) {
                ...
            }
        }
        return sWindowSession
    }
}

3.7.2 WMS.openSession

[—>WindowManagerService.java]

public IWindowSession openSession(IWindowSessionCallback callback, IInputMethodClient client, IInputContext inputContext) {
    //创建Session对象
    Session session = new Session(this, callback, client, inputContext);
    return session;
}

通过Binder调用进入System_server进程创建Session对象,最后再通过Binder传回

创建完ViewRootImpl后再看下它的setView方法

3.7.3 ViewRootImpl.setView

[—>ViewRootimpl.java]

public void setView(View view, WindowManager.LayoutParams attrs, View panelParentView) {
  synchronized (this) {
    ...
    requestLayout();
    ...
    //通过Binder调用,进入system_server进程的Session[见3.8]
    res = mWindowSession.addToDisplay(mWindow, mSeq, mWindowAttributes,
          getHostVisibility(), mDisplay.getDisplayId(),
          mAttachInfo.mContentInsets, mAttachInfo.mStableInsets,
          mAttachInfo.mOutsets, mInputChannel);
    ...
  }
}

调用成员方法requestLayout来请求对应用程序的窗体视图的UI做第一次布局

调用ViewRoot类的成员变量mWindowSession所描述的一个类型为Session的Binder代理对象的成员函数add来请求WindowManagerService增加一个WindowState对象,以便可以用来描述当前正在处理的一个ViewRoot所关联的一个应用程序窗口

3.8 Session.addToDisplay

[—>Session.java]

final class Session extends IWindowSession.Stub implements IBinder.DeathRecipient {

    public int addToDisplay(IWindow window, int seq, WindowManager.LayoutParams attrs, int viewVisibility, int displayId, Rect outContentInsets, Rect outStableInsets, Rect outOutsets, InputChannel outInputChannel) {
        //[见3.9]
        return mService.addWindow(this, window, seq, attrs, viewVisibility, displayId,
                outContentInsets, outStableInsets, outOutsets, outInputChannel);
    }
}

3.9 WMS.addWindow

[—>WindowManagerService.java]

public int addWindow(Session session, IWindow client, int seq, WindowManager.LayoutParams attrs, int viewVisibility, int displayId, Rect outContentInsets, Rect outStableInsets, Rect outOutsets, InputChannel outInputChannel) {
    ...
    WindowToken token = mTokenMap.get(attrs.token);
    //创建WindowState [见3.9.1]
    WindowState win = new WindowState(this, session, client, token,
                attachedWindow, appOp[0], seq, attrs, viewVisibility, displayContent);
    ...
    //调整WindowManager的LayoutParams参数
    mPolicy.adjustWindowParamsLw(win.mAttrs);
    res = mPolicy.prepareAddWindowLw(win, attrs);
    addWindowToListInOrderLocked(win, true);
    // 设置input
    mInputManager.registerInputChannel(win.mInputChannel, win.mInputWindowHandle);
    // [见3.9.2]
    win.attach();
    mWindowMap.put(client.asBinder(), win);

    if (win.canReceiveKeys()) {
        //当该窗口能接收按键事件,则更新聚焦窗口
        focusChanged = updateFocusedWindowLocked(UPDATE_FOCUS_WILL_ASSIGN_LAYERS,
                false /*updateInputWindows*/);
    }
    assignLayersLocked(displayContent.getWindowList());
    ...
}

3.9.1 WindowState

[—>WindowState.java]

WindowState(WindowManagerService service, Session s, IWindow c, WindowToken token,
       WindowState attachedWindow, int appOp, int seq, WindowManager.LayoutParams a,
       int viewVisibility, final DisplayContent displayContent) {
    mService = service;
    mSession = s; //Session的Binder服务端
    mClient = c;  //IWindow的Binder代理端
    mToken = token;
    mOwnerUid = s.mUid; //所对应app的uid
    ...
    DeathRecipient deathRecipient = new DeathRecipient();
    c.asBinder().linkToDeath(deathRecipient, 0); //app端死亡则会有死亡回调

    WindowState appWin = this;
    WindowToken appToken = appWin.mToken;
    while (appToken.appWindowToken == null) {
       WindowToken parent = mService.mTokenMap.get(appToken.token);
       if (parent == null || appToken == parent) {
           break;
       }
       appToken = parent;
    }
    mAppToken = appToken.appWindowToken;

    //创建WindowStateAnimator对象
    mWinAnimator = new WindowStateAnimator(this);
    //创建InputWindowHandle对象
    mInputWindowHandle = new InputWindowHandle(
            mAppToken != null ? mAppToken.mInputApplicationHandle : null, this,
            displayContent.getDisplayId());
}

3.9.2 WindowState.attach

[—>WindowState.java]

void attach() {
    //[见3.9.3]
    mSession.windowAddedLocked();
}

3.9.3 Session.windowAddedLocked

[—>Session.java]

void windowAddedLocked() {
    if (mSurfaceSession == null) {
        mSurfaceSession = new SurfaceSession();
        mService.mSessions.add(this);
        if (mLastReportedAnimatorScale != mService.getCurrentAnimatorScale()) {
            mService.dispatchNewAnimatorScaleLocked(this);
        }
    }
    mNumWindow++;
}

创建SurfaceSession对象,并将当前Session添加到WMS.mSessions成员变量

3.10 总结

WindowManagerService 分析_第2张图片
- 从执行ActivityThread.performLaunchActivity过程开始,创建了如下对象

1.创建了LoadedApk对象

2.创建目标Activity对象

3.创建Application对象

  • 创建完Activity,执行attach操作,初始化成员变量

    1.mWindow:类型为PhoneWindow

    2.mWindowManager:类型为WindowManagerImpl

    3.mToken:远程ActivityRecord的appToken的代理端

  • 执行performResumeActivity过程,回调onResume方

  • 执行addView过程

    1.创建ViewRootImpl对象

    2.创建WMS端的Session代理对象

    3.创建继承于IWindow.Stub的ViewRootImpl.W对象

    4.执行setView()添加视图到WMS

    5.在WMS中创建WindowState对象

    6.updateFocusedWindowLocked来更新聚焦窗口情况

你可能感兴趣的:(android)