カスタムコントロールベースonSaveInstanceState()


JakeWhartonのViewPagerIndicatorを見ていると、CircleIndicatorのonSaveInstanceState()に現在のpage情報が保存されているので、これを学びます.

紹介:


onSaveInstanceState()はActivityが異常回収された場合に呼び出され、通常は呼び出されません.Activityリビルド時にonRestoreInstanceState()メソッドが呼び出され、データのリカバリが行われます.カスタムコントロールを書くときに、必要に応じてこの2つの方法を複写します.
例外は次のとおりです.
  • リソース関連のシステム構成が変更され、Activityが殺され、再作成されます.例えば回転スクリーンなど.
  • システムのリソースメモリが不足しているため、優先度の低いActivityが殺されました.

  • 例:


    CircleIndicatorの一部のコードは、この書き方もカスタムコントロールの標準的な書き方です.詳細については、記事の下部にあるリンクを参照してください.TextViewのソースコードを見ることができますが、これもこのように書かれています.
        @Override
        // 
        public void onRestoreInstanceState(Parcelable state) {
            SavedState savedState = (SavedState)state;
            super.onRestoreInstanceState(savedState.getSuperState());
            mCurrentPage = savedState.currentPage;
            mSnapPage = savedState.currentPage;
            requestLayout();
        }
    
        @Override
        // 
        public Parcelable onSaveInstanceState() {
            Parcelable superState = super.onSaveInstanceState();
            SavedState savedState = new SavedState(superState);
            savedState.currentPage = mCurrentPage;
            return savedState;
        }
    
        // , 。 BaseSavedState 。
        static class SavedState extends BaseSavedState {
            int currentPage;
    
            public SavedState(Parcelable superState) {
                super(superState);
            }
    
            private SavedState(Parcel in) {
                super(in);
                currentPage = in.readInt();
            }
    
            @Override
            public void writeToParcel(Parcel dest, int flags) {
                super.writeToParcel(dest, flags);
                dest.writeInt(currentPage);
            }
    
            @SuppressWarnings("UnusedDeclaration")
            public static final Creator<SavedState> CREATOR = new Creator<SavedState>() {
                @Override
                public SavedState createFromParcel(Parcel in) {
                    return new SavedState(in);
                }
    
                @Override
                public SavedState[] newArray(int size) {
                    return new SavedState[size];
                }
            };
        }

    原理:


    Activityが予期せずに終了すると、ActivityはonSaveInstanceState()を呼び出してデータを保存し、ActivityはWindowにデータの保存を依頼します.Windowは上のトップコンテナにデータの保存を依頼します.最上位コンテナはView Groupで、サブエレメントを一つ一つ通知することでデータを保存します.
    この文章はSaving Android View state correctlyがこの過程をより細かく説明した.
    データを保存する条件:
  • にはIDが必要です.下位層はsparseArrayによってデータを保存するため、ViewIdはkeyとして存在する.
  • ViewIdは独立する必要があります.unique.すべての状態が1つのsparseArrayに保存され、同じidが上書きされます.

  • 参照先:
    理解の促進:Saving Android View state correctly
    カスタムコントロールでのSaveState書き方:stackoverflow