15_ActivityとFragmentのデータ保存とリカバリ

3762 ワード

Activityデータの保存と復元


ActivityのonSaveInstanceState()メソッドが呼び出されると、ActivityはView Hierachy(ビュー階層)の各ビューのステータスを自動的に収集します.ステータスデータを収集するには、内部でViewクラスのステータス保存とリカバリ方法が実装されているコントロールのみが使用されます.onRestoreInstanceState()メソッドが呼び出されると、Activityはこれらの収集されたデータをView HierachyのViewに返信するが、このような返信時のデータとViewの対応関係の根拠は、Viewが以前にデータを保存したときの同じidを提供することであり、通常、レイアウトではandroid:id属性によって定義される.
これらのビューの状態は自動的に保存できますが、Activityメンバー変数はできません.彼らはActivityとともに破棄されます.これらのメンバー変数は、onSaveInstanceState()およびonRestoreInstanceState()の方法で手動で保存および復元する必要があります.
...
@Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putString("data", date);
    }

    @Override
    protected void onRestoreInstanceState(Bundle savedInstanceState) {
        super.onRestoreInstanceState(savedInstanceState);
        date = savedInstanceState.getString("data");
    }


Fragmentデータの保存と復元


FragmentクラスにはonRestoreInstanceState()メソッドはありません.Fragmentがバックスタックから戻ると、Viewは破棄され、再構築されます.この場合、Fragmentは破棄されず、Fragmentインスタンスはインスタンスのメンバー変数を含むそこに残っています.メンバー変数に何もする必要はありませんコードを追加する必要はありません.このため、Instance状態保存は発生しませんでした.
一方、FragmentのViewは破棄され、各内部では、android:freezeText=「true」が設定されている限り、EditTextやTextViewのようなViewクラスの保存とリカバリ方法を実装するViewが自動的に保存され、リカバリされます.
したがって、Fragmentステータスの保存とリカバリの条件は、Fragmentの各View内部でステータスの保存とリカバリ方法が実現されなければならないことです.
Androidは、onSaveInstanceState()およびonRestoreInstanceState()の方法によって、View内部の保存および状態の回復のためのメカニズムを提供する.開発者は、ビューをカスタマイズする際にこの2つの方法を実装すればよい.

Fragment状態とView状態の区別


コードをより明確かつ容易に維持するためには、FragmentステータスとViewステータスを区別する必要があります.ビューに属する任意のプロパティについて、ステータスの保存とリカバリをビュー内部で実行します.Fragmentに属する属性についてはFragment内部で実現すればよい.
...
 @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        date = savedInstanceState.getString("data");
    }

    @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putString("data", date);
    }

Fragment重複問題


問題の説明:
1つの比較的多くの場合、アプリケーションは長時間バックグラウンドにあるが、デバイスのメモリが不足しているためActivityが破棄され、ユーザーが再びアプリケーションを開くとFragmentが重なるという問題が発生する.また、プログラムエラー後にアプリケーションが再起動された場合など
問題の分析:
上記の問題の根源はActivity破棄再構築であり、以前のFragmentは自動的にView状態を保存し、Fragmentのインスタンスは破棄され、再作成時にUIが重なる問題が表示されます.
解決方法:
方法1:Activityが提供するonAttachFragment()メソッドでの処理
@Override
    public void onAttachFragment(android.support.v4.app.Fragment fragment) {
        super.onAttachFragment(fragment);
        if (fragment instanceof  MyFragment) {
            myFragment = (MyFragment) fragment;
        }
    }

方法2:Fragmentを作成する前に判断を追加し、すでに存在するかどうかを判断する
MyFragment fragment = (MyFragment) getSupportFragmentManager().findFragmentByTag("MyFragment");
        if (myFragment == null) {
            myFragment = MyFragment.newInstance();
            fragmentTransaction.add(R.id.content, myFragment, "MyFragment"); 
        } else {
            myFragment = fragment;
        }

方法3:savedInstanceStateを直接利用して判断すればよい
if (savedInstanceState == null) {
            myFragment = MyFragment.newInstance();
            fragmentTransaction.add(R.id.content, myFragment, "MyFragment");
        } else {
            myFragment = (MyFragment) getSupportFragmentManager().findFragmentByTag("MyFragment");
        }

Android ActivityとFragmentの状態保存とリカバリのベストプラクティスAndroid Fragmentの使用について、知らないわけにはいかない注意事項を翻訳します.