android window体系_1.WMS相关的类图

window体系以WindowManagerService为中心

1.WindowManagerService相关类图

在这里插入图片描述

2.类功能介绍

WindowManagerPolicy

提供了window manager 所有UI相关行为。在window manager启动的时候,会创建此接口的实现类,实现类可以定制window层级、特定的window类型、key事件分发和布局

由于这个接口提供了和系统window manager的深度交互,接口里面的有些方法会被一系列限定的context来调用,这些方法编码的时候会带有后缀,代表从哪个线程调用以及持有哪些锁当前支持的后缀有:

  • Ti :从input线程调用
  • Tq:从低层级的输入队列线程调用
  • Lw:从window manager主线程带锁调用
  • Li:从input线程带锁调用

此接口有有个很重要的方法getWindowLayerFromTypeLw,根据窗口类型来返回窗口显示优先级


    /**
     * Returns the layer assignment for the window type. Allows you to control how different
     * kinds of windows are ordered on-screen.
     *
     * @param type The type of window being assigned.
     * @param canAddInternalSystemWindow If the owner window associated with the type we are
     *        evaluating can add internal system windows. I.e they have
     *        {@link Manifest.permission#INTERNAL_SYSTEM_WINDOW}. If true, alert window
     *        types {@link android.view.WindowManager.LayoutParams#isSystemAlertWindowType(int)}
     *        can be assigned layers greater than the layer for
     *        {@link android.view.WindowManager.LayoutParams#TYPE_APPLICATION_OVERLAY} Else, their
     *        layers would be lesser.
     * @return int An arbitrary integer used to order windows, with lower numbers below higher ones.
     */
    default int getWindowLayerFromTypeLw(int type, boolean canAddInternalSystemWindow) 

PhoneWindowManager
为android phone UI实现的WindowManagerPolicy ,在WindowManagerPolicy 的基础上,引入了新的后缀Lp,持有PhoneWindowManager的一个内部锁

Session
该类代表了一个active的客户端seesion,每个进程只能有一个session对象,用来和window manager进行交互

// wms对象,用来与wms进行交互
final WindowManagerService mService;
// 代表和surface flinger的一个连接,用来创建一个或多个Surface实例来合成到屏幕上
SurfaceSession mSurfaceSession;

WindowToken
在window manager中代表一系列相关的window的容器,通常是一个AppWindowToken,是一个将要显示的Activity的句柄。对于嵌套窗口,会创建一个WindowToken作为父窗口来管理子窗口

// 类定义
class WindowToken extends WindowContainer<WindowState>

// 在WindowContainer类定义中,有一个子窗口的列表
// List of children for this window container. List is in z-order as the children appear on
// screen with the top-most window container at the tail of the list.
protected final WindowList<E> mChildren = new WindowList<E>();

AppWindowToken
代表一个特定应用的WindowToken

// 非空的应用token
final IApplicationToken appToken;

ActivityRecord mActivityRecord;

WindowState
代表window manager里面的一个window,其定义如下

class WindowState extends WindowContainer<WindowState>

关键属性有:

final WindowManagerPolicy mPolicy;
final Context mContext;
final Session mSession;
// ViewRootImpl.w类实现了IWindow.Stub
final IWindow mClient;
final WindowId mWindowId;
WindowToken mToken;
// The same object as mToken if this is an app window and null for non-app windows.
AppWindowToken mAppToken;

// 窗口切换动画
final WindowStateAnimator mWinAnimator;

// 窗口层级
int mLayer;
final int mBaseLayer;
final int mSubLayer;
3.Activity启动过程中window相关类的创建过程

详细的启动过程可以参考:ActivityRecord和Activity状态变化

3.1 Token对象的创建

在Activity启动的时候,会先创建一个ActivityRecord对象,此对象的初始化的时候,会创建一个Token对象

对应参考文章的 4.1 第1阶段:从桌面启动DeskClock应用的第5步,new ActivityRecord()

ActivityRecord() {
    appToken = new Token(this, _intent);
}

// ActivityRecord的内部类Token实现了IApplicationToken.Stub
static class Token extends IApplicationToken.Stub

对应的ActivityRecord状态是from:null to:INITIALIZING

08-23 17:30:21.261  1314  4528 V ActivityTaskManager: State movement: ActivityRecord{ed5f802 u0 com.android.deskclock/.DeskClock t-1} from:null to:INITIALIZING reason:ActivityRecord ctor
3.2 AppWindowToken对象的创建

在ActivityStack.startActivityLocked方法里面

对应参考文章的 4.1 第1阶段:从桌面启动DeskClock应用的第7步,startActivityLocked

void startActivityLocked() {
    // 如果ActivityRecord对应的appwindowToken为这,则创建
    if (r.mAppWindowToken == null) {
            r.createAppWindowToken();
    }
}

在ActivityRecord里面,依次调用createAppWindowToken ==> createAppWindow ==> new AppWindowToken

3.3 PhoneWindow对象的创建

在ActivityThread. performLaunchActivity方法里面会调用Activity的attach方法

对应 4.2 第2阶段:DeskClock应用进入创建并启动 第10步

    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, ActivityConfigCallback activityConfigCallback, IBinder assistToken) {
        attachBaseContext(context);

        mFragments.attachHost(null /*parent*/);

        mWindow = new PhoneWindow(this, window, activityConfigCallback);
        // 设置WindowManager,实现类是WindowManagerImpl,WindowManagerImpl具体功能实现是调用WindowManagerGlobal
        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();
   }

WindowManagerGlobal类中包含有IWindowManager(实现类是WindowManagerService)和IWindowSession(实现类是Session)

3.4 Session对象的创建
  • Activity的onCreate方法中会调用setContentView
    其实是调用PhoneWindow对象的setContentView,在此方法中,会创建一个DecorView对象

  • 在ActivityThread.handleResumeActivity里面

ViewManager wm = a.getWindowManager();
...
wm.addView(decor, l);
...

WindowManager定义如下,继承了ViewManager

public interface WindowManager extends ViewManager

getWindowManager方法返回的是mWindowManager对象,在Activity.attach方法里面设置的,返回的一个WindowManagerImpl对象,WindowManagerImpl类的功能主要是通过调用WindowManagerGlobal相对应的方法来实现的.

在WindowManagerGlobal的addView方法里面,会创建一个ViewRootImpl对象,然后调用其setView方法。在ViewRootImpl.setView方法里面会调用Session的addToDisplay

mWindowSession.addToDisplay

其中mWindowSession对象是在ViewRootImpl的构造函数里面初始化的

mWindowSession = WindowManagerGlobal.getWindowSession();

最终调用WindowManagerService的openSession方法来创建Sesison对象

    public static IWindowSession getWindowSession() {
        synchronized (WindowManagerGlobal.class) {
            if (sWindowSession == null) {
                try {
                    IWindowManager windowManager = getWindowManagerService();
                    sWindowSession = windowManager.openSession(
                            new IWindowSessionCallback.Stub() {
                                @Override
                                public void onAnimatorScaleChanged(float scale) {
                                    ValueAnimator.setDurationScale(scale);
                                }
                            });
                } catch (RemoteException e) {
                    throw e.rethrowFromSystemServer();
                }
            }
            return sWindowSession;
        }
    }
    // openSession方法直接返回一个Session对象
    public IWindowSession openSession(IWindowSessionCallback callback) {
        return new Session(this, callback);
    }
3.4 Session对象的创建

Session对象创建后,调用其addToDisplay,最终调用WindowManagerService.addWindow方法,里面会创建WindowState对象

final WindowState win = new WindowState(this, session, client, token, parentWindow, appOp[0], seq, attrs, viewVisibility, session.mUid,
 session.mCanAddInternalSystemWindow);
...
win.attach();
....
// 将WindowState保存到mWindowMap列表里面
mWindowMap.put(client.asBinder(), win);

在addWindow方法里面,会根据不同的类型window来执行不同的逻辑,Window type是定义在WindowManager里面的

接着调用WindowState.attach方法

    void attach() {
        if (localLOGV) Slog.v(TAG, "Attaching " + this + " token=" + mToken);
        mSession.windowAddedLocked(mAttrs.packageName);
    }

在Session的windowAddedLocked里面,会创建SurfaceSession对象,然后mNumWindow数量加1

    void windowAddedLocked(String packageName) {
        mPackageName = packageName;
        mRelayoutTag = "relayoutWindow: " + mPackageName;
        if (mSurfaceSession == null) {
            if (WindowManagerService.localLOGV) Slog.v(
                TAG_WM, "First window added to " + this + ", creating SurfaceSession");
            mSurfaceSession = new SurfaceSession();
            if (SHOW_TRANSACTIONS) Slog.i(
                    TAG_WM, "  NEW SURFACE SESSION " + mSurfaceSession);
            mService.mSessions.add(this);
        }
        mNumWindow++;
    }
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值