用UnityPlayer方式在LinearLayout内显示Unity内容,正常显示后,如果旋转屏幕,会导致Activity退出。如果Unity的Activity是MainActivity则程序会崩溃;不是,则会退回MainActivity。
另外另一个测试日志的Activity也发生了一样的现象,它的问题是出在一个Spinner的onItemSelected里面有个空引用异常。
解决那个异常后,就能正常旋转了,也就是说UnityPlayer也可能是旋转过程中某个地方出错了。
参考:Android 监听屏幕旋转事件(Activity 四 )
根据参考资料,创建一个空的Activity,测试旋转过程中的行为。
public class TestRotateActivity extends AppCompatActivity {
public static String TAG="TestRotateActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
MyLog.setTag(TAG);
MyLog.d("onCreate");
setContentView(R.layout.activity_test_rotate);
}
@Override
protected void onSaveInstanceState(@NonNull Bundle outState) {
super.onSaveInstanceState(outState);
MyLog.d("onSaveInstanceState1:"+outState);
String tempData = "Something you want to save";
outState.putString("data_key", tempData);
}
@Override
public void onSaveInstanceState(@NonNull Bundle outState, @NonNull PersistableBundle outPersistentState) {
super.onSaveInstanceState(outState, outPersistentState);
MyLog.d("onSaveInstanceState2:"+outState);
}
@Override
protected void onRestoreInstanceState(@NonNull Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
MyLog.d("onRestoreInstanceState1:"+savedInstanceState);
}
@Override
public void onRestoreInstanceState(@Nullable Bundle savedInstanceState, @Nullable PersistableBundle persistentState) {
super.onRestoreInstanceState(savedInstanceState, persistentState);
MyLog.d("onRestoreInstanceState2:"+savedInstanceState);
}
@Override
protected void onStart() {
super.onStart();
MyLog.d("onStart");
}
@Override
protected void onStop() {
super.onStop();
MyLog.d("onStop");
}
@Override
protected void onDestroy() {
super.onDestroy();
MyLog.d("onDestroy");
}
@Override
protected void onPause() {
super.onPause();
MyLog.d("onPause");
}
@Override
protected void onResume() {
super.onResume();
MyLog.d("onResume");
}
@Override
protected void onPostCreate(@Nullable Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
MyLog.d("onPostCreate 1:"+savedInstanceState);
}
@Override
public void onPostCreate(@Nullable Bundle savedInstanceState, @Nullable PersistableBundle persistentState) {
super.onPostCreate(savedInstanceState, persistentState);
MyLog.d("onPostCreate 2:"+savedInstanceState);
}
@Override
protected void onPostResume() {
super.onPostResume();
MyLog.d("onPostResume");
}
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
MyLog.d("onNewIntent:"+intent);
}
@Override
public void onCreate(@Nullable Bundle savedInstanceState, @Nullable PersistableBundle persistentState) {
super.onCreate(savedInstanceState, persistentState);
MyLog.d("onCreate2:"+savedInstanceState);
}
@Override
protected void onRestart() {
super.onRestart();
MyLog.d("onResume");
}
}
第一次运行时:onCreate->onStart->onPostCreate1->onResume->onPostResume
旋转时:onPause->onStop->onSaveInstanceState1->onDestroy->onCreate->onStart->onRestoreInstanceState1->onPostCreate1->onResume->onPostResume
没有上面参考资料中的“onCreate(Bundle savedInstanceState)”,从内容来看,其实就是onPostCreate,在Destroy前onSaveInstanceState保存数据,然后在onRestoreInstanceState或者onPostCreate中恢复数据,设计上是这样的吧。
-------------------------------------------
换个思路,Unity导出的Android项目其实也是在Activity里面结合UnityPlayer显示三维内容的,它可以正常旋转。
经过测试,发现是AndroidManifest.xml里面的activity上的设置有关。
默认的是
<activity
android:label="@string/app_name"
android:screenOrientation="fullSensor"
android:launchMode="singleTask"
android:configChanges="mcc|mnc|locale|touchscreen|keyboard|keyboardHidden|navigation|orientation|screenLayout|uiMode|screenSize|smallestScreenSize|fontScale|layoutDirection|density"
android:hardwareAccelerated="false"
android:name="com.DefaultCompany.DeviceDemo.UnityPlayerActivity"
>
其中,android:configChanges="mcc|mnc|locale|touchscreen|keyboard|keyboardHidden|navigation|orientation|screenLayout|uiMode|screenSize|smallestScreenSize|fontScale|layoutDirection|density"
去掉的话,旋转时也会崩溃。
相反,在出问题的项目中的显示unity的activity上加上这个,则能正常旋转。
查一下,发现,原来设置了这个属性后屏幕旋转就不会重新创建新的Activity了,会变成调用onConfigurationChanged了。
参考:Androidmanifest里Activity配置中android:configChanges属性的使用
也就是说,unity的activity的这个配置是说,无法发生什么情况都不要重新创建Activity。
不过,在旋转时有些地方可能需要调整,比如PopupWindow的位置。
用上面参考资料里的
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
int orientation = newConfig.orientation;
if (orientation == Configuration.ORIENTATION_PORTRAIT) {
// TODO:竖屏操作
}
else if (orientation == Configuration.ORIENTATION_LANDSCAPE) {
// TODO:横屏操作
}
}