Android6.0 旋转屏幕(五)WMS启动应用流程(屏幕方向相关)



一、强制设置方向

1.Activity

如果要强制设置一个Activity的横竖屏可以通过Manifest去设置,跟Activity相关的信息都会保存在ActivityInfo当中。

android:screenOrientation=["unspecified" | "user" | "behind" |
                                     "landscape" | "portrait" |
                                     "reverseLandscape" | "reversePortrait" |
                                     "sensorLandscape" | "sensorPortrait" |
                                     "sensor" | "fullSensor" | "nosensor"]

2.Window

如果是要强制设置一个Window的横竖屏可以通过 LayoutParams.screenOrientation来设置。在通过WindowManager.addView的时候把对应的LayoutParams传递给WMS。

WindowManager.LayoutParams.screenOrientation


二、屏幕转屏

2.1 Activity -- 启动一个有设置screenOrientation的Activity

在ActivityStack.startActivityLocked中,AMS会把ActivityRecord相关的Token加到WMS中,有且仅在这个方法中。这时候会把screenOrientation传递过去。

        atoken.requestedOrientation = requestedOrientation; 这个AppToken会在WMS获取相关App Orientation的时候其作用。

mService.mWindowManager.addAppToken(addPos, r.userId, r.appToken,
                                r.task.taskId, r.info.screenOrientation, r.fullscreen,
                                (r.info.flags & ActivityInfo.FLAG_SHOW_ON_LOCK_SCREEN) != 0);
    public void addAppToken(int addPos, int userId, IApplicationToken token,
            int groupId, int requestedOrientation, boolean fullscreen, boolean showWhenLocked) {
        ... ...
        synchronized(mWindowMap) {
            AppWindowToken atoken = findAppWindowToken(token.asBinder());
            if (atoken != null) {
                Slog.w(TAG, "Attempted to add existing app token: " + token);
                return;
            }
            atoken = new AppWindowToken(this, userId, token);
            atoken.inputDispatchingTimeoutNanos = inputDispatchingTimeoutNanos;
            atoken.groupId = groupId;
            atoken.appFullscreen = fullscreen;
            atoken.showWhenLocked = showWhenLocked;
            atoken.requestedOrientation = requestedOrientation;//方向赋值
            if (DEBUG_TOKEN_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(TAG, "addAppToken: " + atoken
                    + " at " + addPos);
            mAppTokens.add(addPos, atoken);
            addAppTokenToAnimating(addPos, atoken);
            mTokenMap.put(token.asBinder(), atoken);

            // Application tokens start out hidden.
            atoken.hidden = true;
            atoken.hiddenRequested = true;

            //dump();
        }
    }


2.2 在启动Activity之前去获取当前WMS中的Orientation的Config

      在resumeTopActivityLocked和realStartActivityLocked中回去获取最新的Orientation的config

       1. 通过mWindowManager.updateOrientationFromAppTokens去更新当前WMS中的Orientation值,把WMS中的config返回给AMS ,这个我们在之前http://blog.csdn.net/kc58236582/article/details/53741445博客分析过了

       2. 通过updateConfigurationLocked去更新AMS中的config,发给每一个ActiviytThread。(会调用每个ActivityThread的onConfigurationChanged函数)

                synchronized (mService) {
                    Configuration config = mService.mWindowManager.updateOrientationFromAppTokens(
                            mService.mConfiguration,
                            next.mayFreezeScreenLocked(next.app) ? next.appToken : null);
                    if (config != null) {
                        next.frozenBeforeDestroy = true;
                    }
                    updated = mService.updateConfigurationLocked(config, next, false, false);
                }

WMS.updateOrientationFroemAppTokens 会直接去调updateOrientationFromAppTokensLocked

          1. 去调用updateOrientationFromAppTokensLocked(false) 做真正的update Orientation的工作,如果返回是true,说明方向发生了变化,就需要去做app的转屏动作。

          2. 如果freezeThisOneIfNeed不为null,说明要做屏幕的转屏操做,就会把当前的atoken freeze掉。

          3. computeNewConfigurationLocked()  计算当前的Configuration,然后返回给AMS。

    private Configuration updateOrientationFromAppTokensLocked(
            Configuration currentConfig, IBinder freezeThisOneIfNeeded) {
        Configuration config = null;

        if (updateOrientationFromAppTokensLocked(false)) {
            if (freezeThisOneIfNeeded != null) {
                AppWindowToken atoken = findAppWindowToken(
                        freezeThisOneIfNeeded);
                if (atoken != null) {
                    startAppFreezingScreenLocked(atoken,
                            ActivityInfo.CONFIG_ORIENTATION);
                }
            }
            config = computeNewConfigurationLocked();

        } else if (currentConfig != null) {
            // No obvious action we need to take, but if our current
            // state mismatches the activity manager's, update it,
            // disregarding font scale, which should remain set to
            // the value of the previous configuration.
            mTempConfiguration.setToDefaults();
            mTempConfiguration.fontScale = currentConfig.fontScale;
            if (computeScreenConfigurationLocked(mTempConfiguration)) {
                if (currentConfig.diff(mTempConfiguration) != 0) {
         
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值