Android6.0 旋转屏幕(四)应用强制设置方向
来源:互联网 发布:比亚乔都市印象150数据 编辑:程序博客网 时间:2024/05/16 08:14
有时候我们也可以强制应用横频,这又是如何做到的?
就是调用了AMS的setRequestedOrientation接口,这个接口先是调用WMS的setAppOrientation函数设置这个Activity在WMS中的方向。然后在调用WMS的updateOrientationFromAppTokens函数旋转屏幕,最后在调用updateConfigurationLocked这个函数之前博客分析过就是是否让Activity重新Launch等。
@Override public void setRequestedOrientation(IBinder token, int requestedOrientation) { synchronized (this) { ActivityRecord r = ActivityRecord.isInStackLocked(token); if (r == null) { return; } if (r.task != null && r.task.mResizeable) { // Fixed screen orientation isn't supported with resizeable activities. return; } final long origId = Binder.clearCallingIdentity(); mWindowManager.setAppOrientation(r.appToken, requestedOrientation); Configuration config = mWindowManager.updateOrientationFromAppTokens( mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null); if (config != null) { r.frozenBeforeDestroy = true; if (!updateConfigurationLocked(config, r, false, false)) { mStackSupervisor.resumeTopActivitiesLocked(); } } Binder.restoreCallingIdentity(origId); } }
我们先看下WMS的setAppOrientation函数,很简单就是找到这个apptoken的APPWindowToken,然后将其requestedOrientation值赋值。
@Override public void setAppOrientation(IApplicationToken token, int requestedOrientation) { if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS, "setAppOrientation()")) { throw new SecurityException("Requires MANAGE_APP_TOKENS permission"); } synchronized(mWindowMap) { AppWindowToken atoken = findAppWindowToken(token.asBinder()); if (atoken == null) { Slog.w(TAG, "Attempted to set orientation of non-existing app token: " + token); return; } atoken.requestedOrientation = requestedOrientation; } }
然后我们再来看WMS的updateOrientationFromAppTokens函数,这个函数主要调用了updateOrientationFromAppTokensLocked函数,这个函数先调用另一个updateOrientationFromAppTokensLocked函数,根据这个函数的返回值,返回true代表要旋转,就调用computeNewConfigurationLocked计算Configuration返回。
private Configuration updateOrientationFromAppTokensLocked( Configuration currentConfig, IBinder freezeThisOneIfNeeded) { if (!mDisplayReady) { return null; } Configuration config = null; if (updateOrientationFromAppTokensLocked(false)) { if (freezeThisOneIfNeeded != null) { AppWindowToken atoken = findAppWindowToken(freezeThisOneIfNeeded); if (atoken != null) { startAppFreezingScreenLocked(atoken); } } 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; computeScreenConfigurationLocked(mTempConfiguration); if (currentConfig.diff(mTempConfiguration) != 0) { mWaitingForConfig = true; final DisplayContent displayContent = getDefaultDisplayContentLocked(); displayContent.layoutNeeded = true; int anim[] = new int[2]; if (displayContent.isDimming()) { anim[0] = anim[1] = 0; } else { mPolicy.selectRotationAnimationLw(anim); } startFreezingDisplayLocked(false, anim[0], anim[1]); config = new Configuration(mTempConfiguration); } } return config; }我们来看下updateOrientationFromAppTokensLocked函数,我们先调用了getOrientationLocked函数获取上次强制设置的方向,如果不同就调用updateRotationUncheckedLocked函数,这个函数之前博客分析过了,流程就一样了。最后就到DisplayManagerService中设置设备的方向。
boolean updateOrientationFromAppTokensLocked(boolean inTransaction) { long ident = Binder.clearCallingIdentity(); try { int req = getOrientationLocked(); if (req != mForcedAppOrientation) { mForcedAppOrientation = req; //send a message to Policy indicating orientation change to take //action like disabling/enabling sensors etc., mPolicy.setCurrentOrientationLw(req); if (updateRotationUncheckedLocked(inTransaction)) { // changed return true; } } return false; } finally { Binder.restoreCallingIdentity(ident); } }最后我们回到AMS的setRequestedOrientation函数,我们调用updateConfigurationLocked函数,当返回false,就是现在的状态要改变(比如重启Activity),然后就调用ActivityStackSupervisor的resumeTopActivitiesLocked函数来启动最上面的Activity。
public void setRequestedOrientation(IBinder token, int requestedOrientation) { synchronized (this) { ActivityRecord r = ActivityRecord.isInStackLocked(token); if (r == null) { return; } if (r.task != null && r.task.mResizeable) { // Fixed screen orientation isn't supported with resizeable activities. return; } final long origId = Binder.clearCallingIdentity(); mWindowManager.setAppOrientation(r.appToken, requestedOrientation); Configuration config = mWindowManager.updateOrientationFromAppTokens( mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null); if (config != null) { r.frozenBeforeDestroy = true; if (!updateConfigurationLocked(config, r, false, false)) { mStackSupervisor.resumeTopActivitiesLocked(); } } Binder.restoreCallingIdentity(origId); } }
2 0
- Android6.0 旋转屏幕(四)应用强制设置方向
- Android6.0 旋转屏幕(五)WMS启动应用流程(屏幕方向相关)
- Android6.0 旋转屏幕(三)应用是否要重启
- Android6.0 旋转屏幕(二)旋转设备
- WM6设置及获取屏幕旋转方向
- #坑2# 强制旋转应用当前屏幕
- Unity3D研究院之设置自动旋转屏幕默认旋转方向
- 打包发布关于设置自动旋转屏幕默认旋转方向
- iOS强制旋转屏幕
- ios屏幕强制旋转
- 如何强制旋转屏幕
- iOS强制屏幕旋转
- iOS屏幕强制旋转
- iOS 强制屏幕旋转
- iOS 强制旋转屏幕
- 屏幕旋转方向
- 如何framework层任意设置Android屏幕的旋转方向
- IOS 6下设置屏幕旋转方向代码
- 支持wmv、mpg、mov、avi格式的网页视频播放代码
- JQuery学习笔记(3)
- Android动态设置view的大小及其位置
- ServletConfig对象
- Android systemUI移植
- Android6.0 旋转屏幕(四)应用强制设置方向
- 关于开关电源PCB设计中存在的问题
- P2P系统中的DHT算法分析
- 八个Docker的真实应用场景
- spring IOC
- wifi的两种工作模式
- iOS关于地图定位基础(一)
- Java8 lambda学习日记(1)
- JAVA WEB 浏览器兼容问题汇总