最近由于要接入一个三方的jar将项目的compileSdkVersion和targetSdkVersion版本升级到了28(原来是26),测试人员在测试时发现android8.0.0版本的手机会莫名crash,crash的原因就是Only fullscreen activities can request orientation。
在我项目的代码中由于用到了滑动返回,为了更好的效果在manifest.xml中将activity的style设定成了透明的,同时我们也规定了页面只能竖向使用,于是这两个条件加上android8.0.0的机制问题就来了。
有了问题没关系,解决问题于是我们找到了一个技术贴,写的不错很详细这里附上链接https://blog.csdn.net/starry_eve/article/details/82777160
大佬总结了两种crash的原因如下:
1.Activity的风格为透明,在manifest文件中指定了一个方向,则在onCreate中crash。
2.Activity的风格为透明,如果调用setRequestedOrientation方法固定方向,则crash。
这两种crash都是只有android8.0.0版本出现的,8.1.0以后就已经修复了,所以我们需要对8.0.0版本进行特殊处理,处理方法如下:
在所有activity的基类BaseActivity中添加下面的逻辑
//在onCreate的时候,先判断,如果透明,直接把方向改为SCREEN_ORIENTATION_UNSPECIFIED:
@Override
protected void onCreate(Bundle savedInstanceState) {
if (Build.VERSION.SDK_INT == Build.VERSION_CODES.O && isTranslucentOrFloating()) {
boolean result = fixOrientation();
XLog.i(XLog.BASE, "onCreate fixOrientation when Oreo, result = " + result);
}
super.onCreate(savedInstanceState);
}
private boolean fixOrientation(){
try {
Field field = Activity.class.getDeclaredField("mActivityInfo");
field.setAccessible(true);
ActivityInfo o = (ActivityInfo)field.get(this);
o.screenOrientation = -1;
field.setAccessible(false);
return true;
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
private boolean isTranslucentOrFloating(){
boolean isTranslucentOrFloating = false;
try {
int [] styleableRes = (int[]) Class.forName("com.android.internal.R$styleable").getField("Window").get(null);
final TypedArray ta = obtainStyledAttributes(styleableRes);
Method m = ActivityInfo.class.getMethod("isTranslucentOrFloating", TypedArray.class);
m.setAccessible(true);
isTranslucentOrFloating = (boolean)m.invoke(null, ta);
m.setAccessible(false);
} catch (Exception e) {
e.printStackTrace();
}
return isTranslucentOrFloating;
}
//然后在设置方向的时候如果透明,直接不执行:
@Override
public void setRequestedOrientation(int requestedOrientation) {
if (Build.VERSION.SDK_INT == Build.VERSION_CODES.O && isTranslucentOrFloating()) {
XLog.i(XLog.BASE, "avoid calling setRequestedOrientation when Oreo.");
return;
}
super.setRequestedOrientation(requestedOrientation);
}