Android系统自动转屏流程(源码分析)

  Android是支持屏幕进行旋转的,经过旋转使得屏幕呈现出竖屏或者横屏的布局。有时咱们在使用的时候会发现,旋转时会有动画。这是由于,为了使用户在使用转屏旋转过程当中提高体验,系统会对屏幕截屏,使用截屏获取的图片进行旋转动画,指导完成旋转,咱们所看到的旋转动画实际上是,旋转开始时系统所截屏幕所作的动画。java

  手机是否支持转屏能够在Setting设定,对于Setting中有关是否自动转屏,PhoneWindowManager中的init()函数中建立了SettingsObserver对象,其observe()方法将监听Settings.System.USER_ROTATION的值。若是设置中打开auto-rotation,会触发以下流程。android

下面对该流程中涉及到的代码进行分析:函数

1AccessibilitySettings类是各手机厂商本身的setting模块中的一个类,该类的命名和方法可能不一样,详细代码见下。oop

2handleLockScreenRotationPreferenceClick()也是AccessibilitySettings.java的方法。在该方法中调用RotationPolicy类的setRotationLockedForAccessbility(),其实就是用户在settings界面点击auto-Rotation传入对应的值。布局

3、下面的各种及方法为android中源码。enable为是否容许自动旋转的使能位。动画

4、在setRotationLock()方法中,根据enable的值,分别执行wms的不容许转屏和容许转屏。spa

5freezeRotation()不容许转屏,thawRotation()容许转屏。这里咱们分析转屏的流程,所以顺着thawRotation()的流程分析。线程

6PhoneWindowManager.javasetUserRotationMode。该方法会在Settings.System中写入值。3d

7PhoneWindowManager中的init()函数中建立了SettingsObserver对象,其observe()方法将监server

Settings.System.USER_ROTATION的值,监听到该值后调用onChange

8该方法是wms在调用freezeRotation()thawRotation()后调用的。

9、这里会触发SettingsObserver.onChange(),其中主要调用了updateSettings()updateRotation()两个函数。其主要的工做是根据须要监听传感器数据,据此判断是否要转屏,若是传感器传回的值改变,则对configuration的各类更新。函数updateSettings()如它的名字主要更新设置信息。若是UserRotation(朝向信息,如Surface.ROTATION_0)和UserRotationModeUSER_ROTATION_FREE vs. USER_ROTATION_LOCKED)有更新,就设置标记updateRotationtrue表示接下去须要更新rotation相关信息。

10、若是UserRotationMode的配置有变,因为须要传感器信息的配合,还需调用updateOrientationListenerLp()来设置或取消监听传感器。

11、假设手机设置为自动旋转,那么PhoneWindowManager会经过MyOrientationListener来监听传感器信息。MyOrientationListenerWindowOrientationListener的继承类,WindowOrientationListenerenable()函数中调用SensorManager提供的registerListener()接口来设置Sensor信息的listener

12、接下来咱们重点分析有关传感器部分的流程。

调用SensorManager提供的registerListener()接口设置Sensor信息的listener

调用SystemSensorManagerregisterListenerImpl注册监听器,当Sensor数据有改变的时候将会回调SensorEventListeneronSensorChanged方法

  手机开机后会建立SystemSensorManager的实例,在其构造函数中,主要作了四件事情:

1)初始化JNI:调用JNI函数nativeClassInit()进行初始化。

2)初始化Sensor列表:调用JNI函数sensors_module_init,对Sensor模块进行初始化,建立了nativeSensorManager的实例。

3)获取Sensor列表:调用JNI函数sensors_module_get_next_sensor()获取Sensor,并存在sHandleToSensor列表中

4)构造SensorThread类:构造线程的类函数,并无启动线程,当有应用注册的时候才会启动线程。

  当有应用程序调用registerListenerImpl()方法注册监听的时候,会调用SensorThread.startLoacked()启动线程。线程只会启动一次,并调用enableSensorLocked()接口对指定的sensor使能,并设置采样时间。SensorThreadRunnable实现了Runnable接口,在SensorThread类中被启动。

 

  首先,registerListenerImpl()中建立SensorEventQueue对象(基类为BaseEventQueue),它是传感器事件的队列,记录须要监听哪些传感器信息。同时也负责与SensorService的链接和通讯,能够说是SensorEventListenerSensorService间的桥梁。SensorEventListenerSensorEventQueue之间是1:1的关系,它们的映射关系保存在成员mSensorListeners中。若是这里注册的SensorEventListener尚未相应的SensorEventQueue,则新建一个,而后经过addSensor()方法将要关注的传感器进行注册。这个过程当中addSensor()调用了enableSensor(),它最终是经过SensorServiceenableDisable()方法来完成注册工做的。这样,SensorService就开始监听该Sensor,当底层有传感器数据来时,SensorService主线程中会调用相应SensorEventConnectionsendEvents()将底层传感器传回的数据发给对应的Client。前面初始化SensorEventQueue时会建立Receiver,它是一个Looper的回调对象,在Client端收到从SensorService来的数据后被回调。当有数据收到时ReceiverhandleEvent()被调用,继而经过JNI调用到SystemSensorManager::dispatchSensorEvent()。接着就调到了WindowOrientationListeneronSensorChanged()函数。该函数将计算是否须要转屏。若是须要转屏,将计算结果传给MyOrientationListeneronProposedRotationChanged()

13回到PhoneWindowManagerupdateSettings()流程。最后若是检测到UserRotationUserRotationMode有更新,会调用updateRotation(),继而调用WMSupdateRotation()保证当前的屏幕方向是一致的。

  若是手机如今转了屏幕,指望转屏事件发生。如前面所说,onProposedRotationChanged()被调用,其中调用updateRotation()函数,随之的updateRotationUncheckedLocked()就是真正执行转屏的地方了。固然除了上面这条种状况会进行转屏,还有其它状况可能会触发转屏,好比应用请求转屏。例如须要横屏的游戏(经过updateOrientationFromAppTokensLocked()方法)。updateRotation()中主要是执行两个函数:updateRotationUncheckedLocked()sendNewConfiguration()。前者执行转屏动做,包含转屏动画等。后者使AMS获取当前新的configuration,而且广播该事件给全部相应的listener

相关文章
相关标签/搜索