我的应用程序中有一个有趣的错误。当用户旋转屏幕时,我丢失了活动中的一些数据。任何人都知道为什么会这样?
答案 0 :(得分:66)
//Use onSaveInstanceState(Bundle) and onRestoreInstanceState
@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
// Save UI state changes to the savedInstanceState.
// This bundle will be passed to onCreate if the process is
// killed and restarted.
savedInstanceState.putBoolean("MyBoolean", true);
savedInstanceState.putDouble("myDouble", 1.9);
savedInstanceState.putInt("MyInt", 1);
savedInstanceState.putString("MyString", "Welcome back to Android");
// etc.
super.onSaveInstanceState(savedInstanceState);
}
//onRestoreInstanceState
@Override
public void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
// Restore UI state from the savedInstanceState.
// This bundle has also been passed to onCreate.
boolean myBoolean = savedInstanceState.getBoolean("MyBoolean");
double myDouble = savedInstanceState.getDouble("myDouble");
int myInt = savedInstanceState.getInt("MyInt");
String myString = savedInstanceState.getString("MyString");
}
这是系统在轮换时删除数据时的保存方式。
答案 1 :(得分:32)
默认情况下,当屏幕旋转时,您的Activity将被终止并重新启动。要确保没有数据丢失,您需要使用生命周期方法正确保存和恢复数据。请参阅Saving Persistent State。
答案 2 :(得分:8)
我发现的最快解决方案是: http://developer.android.com/guide/topics/resources/runtime-changes.html#HandlingTheChange
答案 3 :(得分:7)
这是@ jaisonDavis的有用答案的变体:
int myInt;
String myString;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_verses);
if (savedInstanceState == null) {
Intent intent = getIntent();
myInt = intent.getIntExtra("MyIntIntentKey", DEFAULT_INT);
myString = intent.getStringExtra("MyStringIntentKey", DEFAULT_STRING);
} else { // savedInstanceState has saved values
myInt = savedInstanceState.getInt("MyIntKey");
myString = savedInstanceState.getString("MyStringKey");
}
}
@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
savedInstanceState.putInt("MyIntKey", myInt);
savedInstanceState.putString("MyStringKey", myString);
super.onSaveInstanceState(savedInstanceState);
}
在此示例中,变量在第一次创建活动时从Intent
初始化,但之后会从savedInstanceState
初始化(就像方向更改时一样)。
答案 4 :(得分:4)
在 AndroidManifest.xml 中添加以下代码
<activity android:name=".MainActivity"
android:configChanges="keyboardHidden|orientation|screenSize"
>
答案 5 :(得分:3)
人们已经提供了代码。所以我将添加更多细节。
当屏幕旋转时,Activity的配置会发生变化,因此System会为Activity查找更合适的资源。为此,系统会终止活动的实例并重新创建活动的新实例。
系统尝试使用一组旧的Activity实例的已保存数据(称为实例状态)重新创建实例。 InstanceState是存储在Bundle
对象中的键值对的集合。
默认情况下,系统将View对象保存在Bundle中。例如。
如果您想存储更多数据,这些数据应该可以在更改方向时使用。您应该覆盖onSaveInstanceState(Bundle savedInstanceState)
方法。
@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
// Save the user's current game state
savedInstanceState.putInt(STATE_SCORE, mCurrentScore);
// Always call the superclass so it can save the view hierarchy state
super.onSaveInstanceState(savedInstanceState);
}
如果忘记打电话,那就错了 super.onSaveInstanceState(savedInstanceState)的默认行为 将无效,即
EditText
中的文字将无法保存。 如果你不相信我check this out
很多人都对我感到困惑。我应该选择
onCreate(Bundle savedInstanceState)
OR
onRestoreInstanceState(Bundle savedInstanceState)
没关系。两种方法都在参数中接收相同的包。唯一的区别是您需要在onCreate(Bundle savedInstanceState)
方法中提供空检查。但是,如果您打算使用onRestoreInstanceState(Bundle savedInstanceState)
,请谨慎使用
@Override
public void onRestoreInstanceState(Bundle savedInstanceState) {
// Always call the superclass so it can restore the view hierarchy
super.onRestoreInstanceState(savedInstanceState);
// Restore state members from saved instance
mCurrentScore = savedInstanceState.getInt(STATE_SCORE);
}
请务必致电
super.onRestoreInstanceState(savedInstanceState)
系统默认恢复View层次结构
答案 6 :(得分:2)
setRetainInstance(true);
在OnCreate
上使用此功能答案 7 :(得分:1)
Android引入了ViewModel
,它可以在旋转屏幕时存储复杂对象。
ViewModel
类旨在以生命周期感知的方式存储和管理与UI相关的数据。 ViewModel
类允许数据在配置更改(例如屏幕旋转)中幸免。
请参阅文档
https://developer.android.com/topic/libraries/architecture/viewmodel
答案 8 :(得分:1)
在AndroidManifest.xml中添加以下代码
<activity android:name=".MainActivity"
android:configChanges="keyboardHidden|orientation|screenSize"
>
对我有用
答案 9 :(得分:0)
您可以使用MVVM模式并使用ViewModel来保存数据。因此,当您旋转设备时,您不必担心丢失数据,因为您在ViewModel中隔离了数据,这意味着数据不会受到活动生命周期的影响。 https://developer.android.com/topic/libraries/architecture/viewmodel
答案 10 :(得分:0)
configChanges 解决了我的问题
<activity android:name=".MyActivity"
android:configChanges="orientation|screenSize|screenLayout|keyboardHidden"
android:label="@string/app_name">
答案 11 :(得分:0)
“ViewModel”是一个设计用于在配置更改(例如屏幕旋转)中幸存下来的类,并且可以保留视图所需的信息。当“View”(即片段/活动)通过改变设备的配置或旋转而被销毁时,它的“ViewModel”不会被销毁,并且一个新的View实例将重新连接到同一个“ViewModel”。
ViewModel 中的代码可能是这样的,以便 View 可以保存数据:
private boolean mSomeBooleanData = false;
public boolean getSomeBooleanData(){
return mSomeBooleanData;
}
public void setSomeBooleanData (boolean data) {
mSomeBooleanData = data;
}
现在在 Activity/Fragment 类中的某处,从 ViewModel 调用这些方法,我们可以使用以下方法保存我们想要在旋转期间保存的数据:
mViewModel.setSomeBooleanData(true);
然后在 onResume() 方法中重新创建 Activity/Fragment 类时,我们可以从 ViewModel 中查找保存的数据并对其进行处理:
public void onResume(){
super.onResume();
if (mViewModel.getSomeBooleanData()){
//...Do something when saved data is True
} else {
//...Do something when saved data is False
}
}