用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:橫屏操作
}
}