Android Framework--转屏原理

本文带你从framework的视角了解转屏从产生到结束这一过程,应用开发中转屏相关的知识点已经有很多现成的资料,不在这里的讨论范围。

转屏的流程非常简单,如下:
这里写图片描述

下面将分为三个阶段进行讨论,本文贴出的代码来源于Android N。


转屏的产生

框架利用一定的策略来确定当前的屏幕方向,依据主要是窗口的screenOrientation,以及其它的一些状态,比如系统是否开启了屏幕旋转、系统是否固定了屏幕方向、是否处于dock模式等。

在讲如何确定屏幕方向前,先介绍窗口的screenOrientation。对于一个窗口,根据是否Activity窗口,以不同的方式来声明screenOrientation:

  • Activity窗口:
    1、(静态)AndroidManifest.xml中配置screenOrientation
    2、(动态)通过Activity.setRequestedOrientation()
/**
 * Change the desired orientation of this activity.  If the activity
 * is currently in the foreground or otherwise impacting the screen
 * orientation, the screen will immediately be changed (possibly causing
 * the activity to be restarted). Otherwise, this will be used the next
 * time the activity is visible.
 *
 * @param requestedOrientation An orientation constant as used in
 * {@link ActivityInfo#screenOrientation ActivityInfo.screenOrientation}.
 */
public void setRequestedOrientation(@ActivityInfo.ScreenOrientation int requestedOrientation) {
    if (mParent == null) {
        try {
            ActivityManagerNative.getDefault().setRequestedOrientation(
                    mToken, requestedOrientation);
        } catch (RemoteException e) {
            // Empty
        }
    } else {
        mParent.setRequestedOrientation(requestedOrientation);
    }
}
  • 非Activity窗口:指定WindowManager.LayoutParams.screenOrientation
/**
 * Specific orientation value for a window.
 * May be any of the same values allowed
 * for {@link android.content.pm.ActivityInfo#screenOrientation}.
 * If not set, a default value of
 * {@link android.content.pm.ActivityInfo#SCREEN_ORIENTATION_UNSPECIFIED}
 * will be used.
 */
public int screenOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;

窗口的screenOrientation默认为ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED(不指定方向),另外还有个特殊的值为ActivityInfo.SCREEN_ORIENTATION_BEHIND(由下方的窗口指定方向)。

现在可以开始讲屏幕方向的确定过程,主要是两个步骤:

  1. 从上到下遍历窗口堆栈,在可见的窗口中确定一个基准screenOrientation
    1)非Activity窗口的screenOrientation如果不是上述的两个值,则结束遍历
    2)一旦遍历到一个Activity窗口,接下来仅在Activity窗口中遍历,不再关心非Activity窗口

  2. 根据第一步算出的基准screenOrientation,按照一定策略计算出最终屏幕方向,有兴趣的可以参考源码

frameworks\base\services\core\java\com\android\server\policy\PhoneWindowManager.java

public int rotationForOrientationLw(int orientation, int lastRotation);

根据第一点可以知道,一个比较高层级的非Activity窗口,是可以通过配置screenOrientation来让自己成为基准screenOrientation的确定者,进而影响最终的屏幕方向。

那么转屏的原因很简单,即系统在某一时刻计算出的屏幕方向发生了变化,常

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值