Android获取屏幕旋转角度正确实现 替换废弃windowManager.orientation API
现有代码存在的问题
- 无限递归崩溃:
getOrientation()方法第一行直接调用自身this.getOrientation(),运行后会立刻触发栈溢出,完全无法正常执行 - 传参逻辑错误:
getDisplay()要求传入的是屏幕ID,你传入了递归调用得到的无效值,入参完全不符合方法设计要求 - 空指针风险:
getDisplay(rotation)!!使用非空断言,一旦对应ID的屏幕不存在,会直接触发空指针崩溃 - 类型不匹配:when 表达式的 else 分支只有日志打印,返回值是 Unit 类型,和方法要求返回的 Int 类型冲突,编译阶段就会报错
修正后的符合规范实现
import android.hardware.display.DisplayManager import android.view.Display import android.view.Surface import android.content.pm.ActivityInfo import android.util.Log /** * 根据传入的屏幕ID获取对应Display实例,不传参默认取主屏 */ private fun getDisplay(displayId: Int = Display.DEFAULT_DISPLAY): Display? { val displayManager = baseContext.getSystemService(DisplayManager::class.java) return displayManager?.getDisplay(displayId) } /** * 获取当前屏幕方向,返回值为ActivityInfo中定义的屏幕方向常量 * 异常情况下默认返回竖屏方向 */ fun getOrientation(): Int { val display = getDisplay() ?: run { Log.e("Display", "无法获取对应屏幕实例") return ActivityInfo.SCREEN_ORIENTATION_PORTRAIT } return when (display.rotation) { Surface.ROTATION_0 -> ActivityInfo.SCREEN_ORIENTATION_PORTRAIT Surface.ROTATION_180 -> ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT Surface.ROTATION_90 -> ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE Surface.ROTATION_270 -> ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE else -> { Log.e("Display", "未知的屏幕旋转状态") ActivityInfo.SCREEN_ORIENTATION_PORTRAIT } } }
修正说明
- 移除了无限递归调用,直接获取默认屏幕实例
- 用安全调用代替非空断言,空场景下有兜底返回值不会崩溃
- 所有分支都返回Int类型的方向常量,不存在类型不匹配问题
- 默认适配主屏的旋转获取,不需要额外传入参数,特殊场景要取副屏的话可以手动传入对应的屏幕ID
内容的提问来源于stack exchange,提问作者Georgi Tasev
相关产品推荐
相关产品推荐

