Android Q模拟器中权限请求导致Activity重复创建问题排查
问题根源
这是Android Q(API 29)模拟器/系统的已知Bug,触发条件很明确:当Activity通过代码设置了固定屏幕方向(比如你用的SCREEN_ORIENTATION_SENSOR_LANDSCAPE),同时在启动阶段发起运行时权限请求时,系统会因权限弹窗的临时配置变更触发Activity重建;而重建后你的代码又会再次执行权限请求逻辑,最终形成无限循环。
在Android Pie及以下版本,系统处理权限请求时的配置变更逻辑不同,因此不会出现这个问题。
可行解决方案
方案1:先检查权限状态,避免重复请求
最直接的思路是从根源切断循环——发起权限请求前先判断权限是否已授予,仅当未授予时才执行请求:
private void requestPermissionsOnStartup() { // 先检查权限是否已授予 if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 25547); } }
方案2:在Manifest中固定屏幕方向,替代动态设置
把屏幕方向的配置移到AndroidManifest.xml的Activity标签中,避免在onCreate里动态设置触发额外的配置变更:
<activity android:name=".MainActivity" android:screenOrientation="sensorLandscape"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity>
同时移除MainActivity中setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE);这一行代码。
方案3:阻止配置变化触发Activity重建
在AndroidManifest.xml的Activity标签中添加configChanges属性,让Activity在屏幕方向变化时不重建,而是通过回调处理:
<activity android:name=".MainActivity" android:configChanges="orientation|screenSize|smallestScreenSize"> <!-- 其他配置保持不变 --> </activity>
如果需要处理方向变化后的UI调整,可以重写onConfigurationChanged方法:
@Override public void onConfigurationChanged(@NonNull Configuration newConfig) { super.onConfigurationChanged(newConfig); // 这里可以添加方向变化后的UI适配逻辑 }
方案4:升级系统镜像
如果条件允许,尝试使用更新版本的Android Q模拟器镜像(或直接升级到Android 11及以上),这个Bug在后续的系统更新中已被官方修复。
验证效果
应用启动后,日志中Activity created!只会出现一次,权限请求正常执行,不会再触发无限重建循环。
内容的提问来源于stack exchange,提问作者Violet Giraffe

