Android系统中WindowManagerService的初始化流程

WMS简介:

WindowManagerService,即窗口管理服务,简称WMS。顾名思义,主要用于进行窗口的管理,通过WMS的数据成员就可以看出来;除了管理窗口外,WMS还要对事件进行管理和分发。

WMS可以作为一个系统服务,可以说是系统服务中最复杂的一个服务了,和AMS(ActivityManagerService)称为Android系统框架“双子星”。掌握了这两个服务的原理和使用方法,可以说,就掌握了Android系统框架的95%了。

WMS类图:

代码位置:

framworks/base/services/java/com/android/server/wm/WindowManagerService.java:

其中,只列出WMS部分数据成员和成员函数,说明如下:

//所有当前激活的客户端sessions,正是这些session来请求WMS的资源
    final HashSet<Session> mSessions = new HashSet<Session>();

    //真正的窗口对象
    final HashMap<IBinder, WindowState> mWindowMap = new HashMap<IBinder, WindowState>();

    //已经完成启动的应用列表
    final ArrayList<AppWindowToken> mFinishedStarting = new ArrayList<AppWindowToken>();

    //渐变窗口列表
    final ArrayList<FakeWindowImpl> mFakeWindows = new ArrayList<FakeWindowImpl>();

    //正在改变尺寸的窗口列表
    final ArrayList<WindowState> mResizingWindows = new ArrayList<WindowState>();

    //动画结束并且马上被移除的窗口列表
    final ArrayList<WindowState> mPendingRemove = new ArrayList<WindowState>();

    //surface马上要被释放的窗口列表
    final ArrayList<WindowState> mDestroySurface = new ArrayList<WindowState>();

    //失去输入焦点并且等待新的焦点的窗口列表
    ArrayList<WindowState> mLosingFocus = new ArrayList<WindowState>();

onTransact():用于进程间通信。作为服务,怎么能少了onTransact呢。 

WMS的初始化:

和其它Framework层的许多service一样,WMS也是在system_server进程中启动的,WMS启动代码:

framworks/base/services/java/com/android/server/SystemServer.java:

wm = WindowManagerService.main(context, power,
                    factoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL,
                    !firstBoot, onlyCore);
            ServiceManager.addService(Context.WINDOW_SERVICE, wm);

创建WMS实例,并且添加到service管理器中。注意,这段代码是在ServerThread的run函数中进行的,而且,wm是ServerThread线程的一个数据成员。整个AndroidFramework层的很多组件,都是ServerThread的数据成员,ServerThread是Framework的核心,而组成这个核心的是各个service。

WMS的实现:

framworks/base/services/java/com/android/server/wm/WindowManagerService.java:

从main函数开始来看:

public static WindowManagerService main(Context context,
            PowerManagerService pm, boolean haveInputMethods, boolean allowBootMsgs,
            boolean onlyCore) {
        WMThread thr = new WMThread(context, pm, haveInputMethods, allowBootMsgs, onlyCore);
        thr.start();

        synchronized (thr) {
            while (thr.mService == null) {
                try {
                    thr.wait();
                } catch (InterruptedException e) {
                }
            }
            return thr.mService;
        }
    }

 main函数返回的是本身这个对象,而且是通过线程WMThread返回的,也即WMThread这个线程创建的对象拥有WindowManagerService的实例的句柄。那么,主要看WMThread这个线程的实现(在源码中w,紧接着main函数的下面):w

static class WMThread extends Thread {
        WindowManagerService mService;

        private final Context mContext;
        private final PowerManagerService mPM;
        private final boolean mHaveInputMethods;
        private final boolean mAllowBootMessages;
        private final boolean mOnlyCore;

        public WMThread(Context context, PowerManagerService pm,
                boolean haveInputMethods, boolean allowBootMsgs, boolean onlyCore) {
            super("WindowManager");
            mContext = context;
            mPM = pm;
            mHaveInputMethods = haveInputMethods;
            mAllowBootMessages = allowBootMsgs;
            mOnlyCore = onlyCore;
        }

        @Override
        public void run() {
            Looper.prepare();
            //Looper.myLooper().setMessageLogging(new LogPrinter(
            //        android.util.Log.DEBUG, TAG, android.util.Log.LOG_ID_SYSTEM));
            WindowManagerService s = new WindowManagerService(mContext, mPM,
                    mHaveInputMethods, mAllowBootMessages, mOnlyCore);
            android.os.Process.setThreadPriority(
                    android.os.Process.THREAD_PRIORITY_DISPLAY);
            android.os.Process.setCanSelfBackground(false);

            synchronized (this) {
                mService = s;
                notifyAll();
            }

            // For debug builds, log event loop stalls to dropbox for analysis.
            if (StrictMode.conditionallyEnableDebugLogging()) {
                Slog.i(TAG, "Enabled StrictMode logging for WMThread's Looper");
            }

            Looper.loop();
        }
    }

可以看到,WHThread是一个静态内部类,有一个WindowManagerService的数据成员。在这个线程的run方法中,调用了WindowManagerService的构造函数(哦,原来是在这里创建的WindowManagerService的实例),创建完成后,把这个实例就保存起来:

            synchronized (this) {
                mService = s;
                notifyAll();
            }

 注意,这里用同步,一定得等到WindowManagerService的实例s被创建好之后,才能进行以上代码的执行。

接着,来看WindowManagerService的构造函数:

    private WindowManagerService(Context context, PowerManagerService pm,
            boolean haveInputMethods, boolean showBootMsgs, boolean onlyCore) {
        mContext = context;
        mHaveInputMethods = haveInputMethods;
        mAllowBootMessages = showBootMsgs;
        mOnlyCore = onlyCore;
        mLimitedAlphaCompositing = context.getResources().getBoolean(
                com.android.internal.R.bool.config_sf_limitedAlpha);
        mHeadless = "1".equals(SystemProperties.get(SYSTEM_HEADLESS, "0"));

        mPowerManager = pm;
        mPowerManager.setPolicy(mPolicy);
        PowerManager pmc = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
        mScreenFrozenLock = pmc.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
                "SCREEN_FROZEN");
        mScreenFrozenLock.setReferenceCounted(false);

        mActivityManager = ActivityManagerNative.getDefault();
        mBatteryStats = BatteryStatsService.getService();

        // Get persisted window scale setting
        mWindowAnimationScale = Settings.System.getFloat(context.getContentResolver(),
                Settings.System.WINDOW_ANIMATION_SCALE, mWindowAnimationScale);
        mTransitionAnimationScale = Settings.System.getFloat(context.getContentResolver(),
                Settings.System.TRANSITION_ANIMATION_SCALE, mTransitionAnimationScale);
        mAnimatorDurationScale = Settings.System.getFloat(context.getContentResolver(),
                Settings.System.ANIMATOR_DURATION_SCALE, mTransitionAnimationScale);

        // Track changes to DevicePolicyManager state so we can enable/disable keyguard.
        IntentFilter filter = new IntentFilter();
        filter.addAction(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
        mContext.registerReceiver(mBroadcastReceiver, filter);

        mHoldingScreenWakeLock = pmc.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK
                | PowerManager.ON_AFTER_RELEASE, "KEEP_SCREEN_ON_FLAG");
        mHoldingScreenWakeLock.setReferenceCounted(false);

        mInputManager = new InputManagerService(context, mInputMonitor);
        mAnimator = new WindowAnimator(this, context, mPolicy);

        PolicyThread thr = new PolicyThread(mPolicy, this, context, pm);
        thr.start();

        synchronized (thr) {
            while (!thr.mRunning) {
                try {
                    thr.wait();
                } catch (InterruptedException e) {
                }
            }
        }

        mInputManager.start();

        // Add ourself to the Watchdog monitors.
        Watchdog.getInstance().addMonitor(this);
        mFxSession = new SurfaceSession();

        Surface.openTransaction();
        createWatermark();
        Surface.closeTransaction();
    }

在WindowManagerService的构造函数中,大部分代码都是在进行数据成员的初始化。WindowManagerService声明了大量的系统框架类的实例,例如:

mContext:运行环境上下文;

mPowerManager:电源管理相关;

mActivityManager:用于管理activity管理;

mInputManager:输入法相关;

mBatteryStats:电池状态相关;

除了初始化这些数据成员外,构造函数中,比较重要的代码如下:

注册了receiver:

IntentFilter filter = new IntentFilter();
//用于接收设备状态的变化        filter.addAction(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
        mContext.registerReceiver(mBroadcastReceiver, filter);

//用于接收电源状态的变化

        mHoldingScreenWakeLock = pmc.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK
                | PowerManager.ON_AFTER_RELEASE, "KEEP_SCREEN_ON_FLAG");
        mHoldingScreenWakeLock.setReferenceCounted(false);
 

还创建了一个线程PolicyThread :

PolicyThread thr = new PolicyThread(mPolicy, this, context, pm);
        thr.start();

和WMThread类似,这个线程也是一个静态内部类,它主要的作用是配合WindowManagerPolicy来完成整个Service功能的实现。

        mInputManager.start(); //开启输入法

        Surface.openTransaction(); //打开surface事务
 

至此,整个WMS就初始化完成了。

可以说,真个初始化过程要比上面的流程复杂的多,不可能面面俱到,仅抛砖引玉。

WMS的使用:

在Android应用程序开发时,是通过WindowManager来访问WMS提供的服务的。

例如,获取WindowManager的代码如下:

WindowManager wm = (WindowManager)getSystemService(Context.WINDOW_SERVICE);

 给一个Activity动态添加一个Button的代码如下:

        WindowManager wm = (WindowManager)getSystemService(Context.WINDOW_SERVICE);
        Button btnView = new Button(this);
        btnView.setText("Hello WM!");
        WindowManager.LayoutParams mParams = new WindowManager.LayoutParams();
        wm.addView(btnView, mParams);


  • 3
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
Android 13(即 Android 3.2),DisplayMetrics的初始化流程Android 11(即 Android 4.0)类似,但具体实现方式有些细微差别。 1. WindowManagerService的构造函数创建了DisplayManagerService对象: ``` mDisplayManager = new DisplayManagerService(context, wmHandler); ``` 2. DisplayManagerService的构造函数初始化了DisplayAdapter集合,然后通过DisplayManagerGlobal.getInstance()方法获取DisplayManagerGlobal对象: ``` mDisplayAdapters = new ArrayList<DisplayAdapter>(); mDisplayAdapters.add(new LocalDisplayAdapter(this)); mGlobal = DisplayManagerGlobal.getInstance(); ``` 3. DisplayManagerGlobal的构造函数创建了DisplayManager对象,并调用DisplayManager对象的init()方法初始化DisplayMetrics: ``` mDm = new DisplayManagerService(context.getApplicationContext(), wmHandler); mDm.init(); ``` 4. DisplayManagerService的init()方法初始化了DisplayPowerController对象,然后遍历DisplayAdapter集合调用其init()方法,最后计算出DisplayMetrics: ``` mPowerController = new DisplayPowerController(context, this, mHandler, mBlanker, mDisplayReadyListener); for (DisplayAdapter adapter : mDisplayAdapters) { adapter.registerLocked(); adapter.initializeLocked(); } mDisplayInfos = mTempDisplayInfos.toArray(new DisplayDeviceInfo[mTempDisplayInfos.size()]); calculateInitialDisplayMetricsLocked(); ``` 其,calculateInitialDisplayMetricsLocked()方法的实现如下: ``` private void calculateInitialDisplayMetricsLocked() { final int width = mDisplayInfos[0].mode.hResolution; final int height = mDisplayInfos[0].mode.vResolution; final float refreshRate = mDisplayInfos[0].mode.refreshRate; final float xdpi = width * 25.4f / mDisplayInfos[0].mode.physicalWidth; final float ydpi = height * 25.4f / mDisplayInfos[0].mode.physicalHeight; final float density = (xdpi + ydpi) / 2; final int densityDpi = (int) (density * 160 + 0.5f); mInitialDisplayWidth = width; mInitialDisplayHeight = height; DisplayMetrics metrics = new DisplayMetrics(); metrics.density = density; metrics.densityDpi = densityDpi; metrics.widthPixels = width; metrics.heightPixels = height; metrics.xdpi = xdpi; metrics.ydpi = ydpi; mInitialDisplayDensity = densityDpi; mCompatibleScreenWidthDp = (int) (width / (densityDpi / 160.0f)); mCompatibleScreenHeightDp = (int) (height / (densityDpi / 160.0f)); mDisplayMetrics.setTo(metrics); } ``` 可以看到,与 Android 11 的实现非常类似,只是计算方法略有不同。在 Android 13 ,DisplayMetrics的xdpi是通过计算屏幕物理宽度和分辨率得出的。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

liranke

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值