Handle screen rotation without losing data - Andro

2019-05-13 12:18发布

我变得疯狂搞清楚什么是处理屏幕旋转的最佳方式。 我在这里读几百个问题/答案,但我真的很困惑。

我如何保存myClass的数据重新创建活动之前,这样我就可以把一切都重新绘制活动,而另一种无用的初始化?

难道还有比parcelable一个更清洁,更好的办法?

我需要处理的旋转,因为我想改变布局风景模式。

public class MtgoLifecounterActivity extends Activity {

    MyClass myClass;

    // Called when the activity is first created
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        If ( ?? first run...myClass == null ? ) {
            myClass = new MyClass();
        } else {
            // do other stuff but I need myClass istance with all values.
        }
        // I want that this is called only first time. 
        // then in case of rotation of screen, i want to restore the other instance of myClass which
        // is full of data.
    }

Answer 1:

可以使用覆盖方法onSaveInstanceState()onRestoreInstanceState() 或停止呼叫onCreate()在屏幕旋转只是在你的清单XML中加入这一行android:configChanges="keyboardHidden|orientation"

注意:您的自定义类必须实现Parcelable下面的例子。

@Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putParcelable("obj", myClass);
    }

@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
 // TODO Auto-generated method stub
 super.onRestoreInstanceState(savedInstanceState);
 myClass=savedInstanceState.getParcelable("obj"));
}

public class MyParcelable implements Parcelable {
     private int mData;

 public int describeContents() {
     return 0;
 }

 /** save object in parcel */
 public void writeToParcel(Parcel out, int flags) {
     out.writeInt(mData);
 }

 public static final Parcelable.Creator<MyParcelable> CREATOR
         = new Parcelable.Creator<MyParcelable>() {
     public MyParcelable createFromParcel(Parcel in) {
         return new MyParcelable(in);
     }

     public MyParcelable[] newArray(int size) {
         return new MyParcelable[size];
     }
 };

 /** recreate object from parcel */
 private MyParcelable(Parcel in) {
     mData = in.readInt();
 }


}


Answer 2:

清单中的活动代码,你应该有提

<activity
        android:name="com.example.ListActivity"
        android:label="@string/app_name" 
        android:configChanges="keyboardHidden|orientation">

如果您使用的是Android 2.3(API等级13)及以上使用

<activity
        android:name="com.example.Activity"
        android:label="@string/app_name" 
        android:configChanges="keyboardHidden|orientation|screenSize">

它应该有工作。

它将工作只与活动标签,而不是与应用标签



Answer 3:

可能这是已经解决了,但只是为新成员谁粘贴了一个小更新,只需看一下谷歌的开发者网站 ,从API等级13,你只需要添加此代码的体现:

<activity android:name=".SplashScreensActivity"
          android:configChanges="orientation|keyboardHidden|screenSize"
          android:label="@string/app_name">

当这些配置中的一种改变,SplashScreensActivity不会重新启动。 相反,SplashScreensActivity接听电话时onConfigurationChanged()。 该方法被传递一个配置对象,指定新的设备配置。 通过读取配置领域,你能确定新的配置,并通过更新在界面中使用的资源进行相应的更改。 在此方法被调用的时候,您的活动的资源对象更新返回基于新的配置资源,让您可以轻松重置您的UI元素没有系统重新启动活动。



Answer 4:

这里的问题是,你正在失去的应用程序的“状态”。 在哎呀,什么是国家? 变量! 究竟! 因此,当你失去你的变量的数据。

现在,这里是你能做什么,找出哪些正在失去他们的状态变量。

当你旋转你的设备,你现在的活动被完全破坏,即通过云的onSaveInstanceState() onPause() onStop() onDestroy()和一个新的活动,创建完全其中经过onCreate() onStart() onRestoreInstanceState。

在大胆的两种方法, 的onSaveInstanceState()保存其将要毁灭,本活动的实例。 onRestoreInstanceState这种方法恢复先前活动的保存状态。 这样你就不会失去你以前的应用程序的状态。

这里是你如何使用这些方法。

 @Override
    public void onSaveInstanceState(Bundle outState, PersistableBundle outPersistentState) {
        super.onSaveInstanceState(outState, outPersistentState);

        outState.putString("theWord", theWord); // Saving the Variable theWord
        outState.putStringArrayList("fiveDefns", fiveDefns); // Saving the ArrayList fiveDefns
    }

    @Override
    public void onRestoreInstanceState(Bundle savedInstanceState, PersistableBundle persistentState) {
        super.onRestoreInstanceState(savedInstanceState, persistentState);

        theWord = savedInstanceState.getString("theWord"); // Restoring theWord
        fiveDefns = savedInstanceState.getStringArrayList("fiveDefns"); //Restoring fiveDefns
    }

编辑: 更好的方法:对保持数据的上述做法是不保持生产代码/应用数据的最佳方式。 谷歌IO 2017年推出视图模型来保护您的数据免受形状变化(如屏幕旋转)。 保持使用变量活动中的所有数据是不是一个好的软件设计和违反了单一职责原则 ,因此使用视图模型从活动分开您的数据存储。

  • 视图模型将负责将要显示的数据。
  • 活动负责将如何显示数据。
  • 使用额外的仓储类,如果你有存储数据的日益复杂。

这只是对单独的类和自己的责任,同时使良好architectured的应用程序,这将很长的路要走的方式之一。



Answer 5:

有关于这个两(好)的方式。 让你的类实现Parcelable并把它放在一个包中onSaveInstanceState()或者,如果是更复杂(例如的AsyncTask),换来的却onRetainNonConfigurationInstance()

再有就是还偷懒的方法,你只是停止反应配置更改。



Answer 6:

如果你没有需要重新启动你的活动刚刚设置的configChanges上在AndroidManifest.xml这个您的活动属性:

    android:configChanges="keyboard|keyboardHidden|orientation"

这会告诉你要采取的处理旋转照顾操作系统,并不会重新启动您的活动。 使用这种方法将消除需要你有保存任何一种状态。



文章来源: Handle screen rotation without losing data - Android