1.原因:
在解决页面跳转时黑屏或者白屏时添加了true, 然后这个时候又设置了页面的方向,从而导致了这个问题。
源码分析问题: 在26的编译版本时是可以正常的使用的,但是当把编译版本升级到27时,就会出现"Only fullscreen activities can request orientation"异常。对源码的分析,得出这是google出于安全的考虑,对android8.0以后的版本做的处理,当一个Activity固定方向并且是透明的,在8.0以后的版本中就会抛出异常
Entry ent = AttributeCache.instance().get(packageName,realTheme, com.android.internal.R.styleable.Window, userId);
final boolean translucent = ent != null && (ent.array.getBoolean(com.android.internal.R.styleable.Window_windowIsTranslucent, false)|| (!ent.array.hasValue(
com.android.internal.R.styleable.Window_windowIsTranslucent) && ent.array.getBoolean(com.android.internal.R.styleable.Window_windowSwipeToDismiss,false)));
fullscreen = ent != null && !ent.array.getBoolean(com.android.internal.R.styleable.Window_windowIsFloating, false) && !translucent;
fullscreen = ent != null && !ActivityInfo.isTranslucentOrFloating(ent.array);
noDisplay = ent != null && ent.array.getBoolean(com.android.internal.R.styleable.Window_windowNoDisplay, false);
if (ActivityInfo.isFixedOrientation(requestedOrientation) && !fullscreen && appInfo.targetSdkVersion > O) {
throw new IllegalStateException("Only fullscreen activities can request orientation");
}
上面是27的源码片段,通过上面我们可以看出当 三个条件同时满足的时候,系统会抛出"Only fullscreen activities can request orientation"异常。先分别来说说这三个条件都表示什么意思:
- ActivityInfo.isFixedOrientation(requestedOrientation) ——
表示判断当前的|Activity是否固定了方向,truea为固定了方向。 - fullscreen —— 表示Activity是否是透明的或者是否悬浮在Activity上,是透明的或者悬浮在Activity上fullscreen就等于false.
以下三种情况认为不是“fullscreen“:
- “windowIsTranslucent”为true;
- “windowIsTranslucent”为false,但“windowSwipeToDismiss”为true;
- “windowIsFloating“为true;
- appInfo.targetSdkVersion > O —— 表示编译版本号大于26
当以上的三个条件同时满足的时候,系统框架就会抛出异常,那意思我们只能让上面的条件不满足就可以了
问题解决
- 不固定Activity的方向
- 不适配8.0及以上手机(当你看到这个问题时,肯定是要适配8.0及以上的,所以当我没有说)
- 修改AppTheme的样式为下,windowIsTranslucent设置为false,同时设置windowDisablePreview为true.(这个方法,可以同时满足透明和固定方向)
<resources>
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
<!-- Customize your theme here. -->
<item name="android:windowFullscreen">true</item>
<item name="android:windowIsTranslucent">false</item>
<item name="android:windowDisablePreview">true</item>
</style>
</resources>
注:android 9.0 去掉了这个限制,原来Activity中对透明Activity的限制取消了。
参考:https://blog.csdn.net/LoveDou0816/article/details/79129324
2.黑/白屏原因:
当然白色闪屏的停留是因为 application 的主题样式android:theme="@style/AppTheme" 使用了 Theme.Light 题导致的,Light 样式的 windowBackground、colorBackground、colorForeground 等属性的值均为 light 也就是白色偏亮,所以才会出现白色闪屏。如果使用了 Theme.Black就会出现黑屏。
解决黑白屏的方法有两种方法:
方法有两种,一种是为them设置背景,二是为them设置透明属性。
方式一:设置背景(windowBackground)
<!-- 为 Theme 设置背景图 -->
<style name="AppTheme" parent="android:style/Theme.Black.NoTitleBar.Fullscreen">
<item name="android:windowBackground">@drawable/splash_bg</item>
</style>
设置背景后,启动程序时会先显示这个图片,因而避免了黑白屏。
方式二:设置透明度(windowIsTranslucent)
<!-- 为 Theme 设置透明属性 -->
<style name="AppTheme" parent="android:style/Theme.Black.NoTitleBar.Fullscreen">
<item name="android:windowIsTranslucent">true</item>
</style>
程序启动后不会黑屏而是透明,等到界面初始化完成后才一次性显示出来。
两者的优缺点:
- 为 Theme 设置背景图 给人程序启动快的感觉,界面先显示背景图,然后再刷新其他界面控件,刷新不同步。
- 为 Theme 设置透明属性 给人程序启动慢的感觉,界面会一次性刷出来,刷新同步。
黑白屏问题参考:https://blog.csdn.net/fancylovejava/article/details/39643449