私のアプリケーションには少し面白いバグがあります。ユーザーが画面を回転させると、アクティビティのデータの一部が失われます。なぜこれが起こるのかを知っている人はいますか?
デフォルトでは、画面が回転するとアクティビティが強制終了され、再起動されます。データが失われないようにするには、ライフサイクルメソッドを使用してデータを適切に保存および復元する必要があります。 永続状態の保存 を参照してください。
//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");
}
これは、システムが回転時にデータを削除するときにデータを保存する方法です
@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
から初期化されます(向きが変わるときなど)。
AndroidManifest.xmlに次のコードを追加します
<activity Android:name=".MainActivity" Android:configChanges="keyboardHidden|orientation|screenSize" >
人々はすでにコードを提供しています。そのため、これについてさらに詳細を追加します。
画面が回転すると、アクティビティの構成が変更されるため、システムはアクティビティにより適したリソースを探します。この目的のために、システムはアクティビティのインスタンスを強制終了し、アクティビティの新しいインスタンスを再作成します。
システムは、instance stateと呼ばれる古いアクティビティインスタンスの保存データのセットを使用して、インスタンスを再作成しようとします。 InstanceStateは、Bundle
オブジェクトに格納されたKey-Valueペアのコレクションです。
デフォルトでは、システムは、たとえばバンドルにビューオブジェクトを保存します。
向きの変更に耐えるデータをさらに保存したい場合。 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
のテキストは保存されません。私を信じないなら チェックアウト
私を含めて多くの人が混乱します。選ぶべきですか
onCreate(Bundle savedInstanceState)
OR
onRestoreInstanceState(Bundle savedInstanceState)
問題ではありません。両方のメソッドは、パラメーターで同じバンドルを受け取ります。唯一の違いは、onCreate(Bundle savedInstanceState)
メソッドでnullチェックを提供する必要があることです。ただし、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)
を呼び出します
AndroidManifest.xmlに次のコードを追加します
<activity Android:name=".MainActivity"
Android:configChanges="keyboardHidden|orientation|screenSize"
>
わたしにはできる
setRetainInstance(true);
OnCreateでこれを使用します
Androidは、画面が回転したときに複雑なオブジェクトを保存できるViewModel
を導入しました。 ViewModel
クラスは、ライフサイクルを意識した方法でUI関連データを保存および管理するように設計されています。 ViewModel
クラスを使用すると、データを画面の回転などの構成変更に耐えることができます。
ドキュメントを参照してください
https://developer.Android.com/topic/libraries/architecture/viewmodel
MVVMパターンを使用し、ViewModelを使用してデータを保存できます。したがって、デバイスをローテーションするときに、ViewModelでデータを分離したため、データが失われる心配はありません。つまり、データはアクティビティライフサイクルの影響を受けません。 https://developer.Android.com/topic/libraries/architecture/viewmodel