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

 

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