21

onSaveInstanceStatesが呼び出されないという同様の質問をいくつか見ましたFragmentが、私の場合、 s は正常に動作し、問題を抱えてFragmentいるのはメインです。FragmentActivity

関連するコードはかなり単純に見えます。

public class MyFActivity extends FragmentActivity implements ActionBar.TabListener { 
    String[] allValues; // data to save

    @Override
    protected void onSaveInstanceState (Bundle outState) {
        Log.d("putting it!", allValues.toString());
        outState.putStringArray("allValues", allValues);
        super.onSaveInstanceState(outState);
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (savedInstanceState != null) {
            allValues = savedInstanceState.getStringArray("allValues");
            Log.d("getting it!", allValues.toString());
        }
    }
}

(戻るボタンを使用して) アクティビティを一時停止するonSaveInstanceStateと、 は呼び出されないため、アプリの再開時にsavedInstanceState常にメソッドnull内にあります。onCreate次のようなブロックを追加してみました。

@Override
public void onPause() {
    super.onPause();
    onSaveInstanceState(new Bundle());      
}

これはhttps://stackoverflow.com/a/14195202/362657で提案されましたが、onSaveInstanceState呼び出されている間はメソッド内にsavedInstanceState残ります。私は何が欠けていますか?nullonCreate

4

3 に答える 3

84

ここでの問題は、どのように機能するかを誤解していることですonSaveInstanceState。OS がメモリ上の理由または構成の変更のために / を破棄する必要がある場合に備えて、 Activity/の状態を保存するように設計されています。Fragmentこの状態は、/ が/に戻って再起動されonCreateたときに戻されます。ActivityFragment

ではFragment、すべてのライフサイクル コールバックが親に直接関連付けられていActivityます。そのため、親がonSaveInstanceState呼び出されたFragmentときに呼び出されます。ActivityonSaveInstanceState

(戻るボタンを使用して) アクティビティを一時停止すると、onSaveInstanceState は呼び出されないため、アプリの再開時に onCreate メソッド内で savedInstanceState は常に null になります。

押し戻すと、ユーザーは を破棄しActivity、したがってその子を破棄します。インスタンスが破棄されるFragmentため、 を呼び出す理由はありません。onSaveInstanceStateを再度開くActivityと、保存された状態のない新しいインスタンスであるため、Bundle渡されるのonCreateは ですnull。これは設計どおりに動作しています。ただし、デバイスを回転させたり、ホーム ボタンを押してみると、Activityとその子FragmentonSaveInstanceState呼び出され、onCreateに戻ったときに渡されたことがわかります。

ライフサイクルコールバックを直接呼び出すべきではないため、あなたが追加したハックonSaveInstanceState(new Bundle());の内部で直接呼び出すことonPauseは非常に悪い習慣です。これを行うと、アプリが違法な状態になる可能性があります。

アプリのインスタンスを超えてデータを保持することが本当に必要な場合は、より高度なデータ用にSharedPreferencesまたはデータベースを使用することを検討することをお勧めします。その後、永続データをonPause()変更するたびに保存できます。

お役に立てれば。

于 2013-04-10T20:31:39.770 に答える
10

受け入れられた回答の更新で:

を(ではなく)とともにonSaveInstanceState使用している場合、フラグメントのが呼び出されることがあります。ViewPagerFragmentStatePagerAdapterFragmentPagerAdapter

FragmentStatePagerAdapter

このバージョンのページャーは、多数のページがある場合に便利で、リスト ビューのように機能します。ページがユーザーに表示されない場合、フラグメント全体が破棄され、そのフラグメントの保存された状態のみが保持されます。これにより、ページャーは、FragmentPagerAdapter と比較して、訪問した各ページに関連付けられたメモリをはるかに少なく保持できますが、ページを切り替えるときにオーバーヘッドが増える可能性があります。

そして忘れないでください:

FragmentPagerAdapter を使用する場合、ホスト ViewPager には有効な ID セットが必要です。

于 2014-01-29T18:31:00.487 に答える
0

質問に対する正確な回答ではありませんが、誰かの一日を助けるかもしれません。私の場合、私は電話しました

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

上記のコードを以下のように置き換えたところ、うまくいきました

@Override
protected void onSaveInstanceState(@NonNull Bundle outState) {
    super.onSaveInstanceState(outState);
}
于 2020-07-30T14:38:18.413 に答える