UnityAndroid(6) 旋轉問題

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

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章