首页 > 学院 > 开发设计 > 正文

自定义控件基础 onSaveInstanceState()

2019-11-08 00:29:26
字体:
来源:转载
供稿:网友

在看JakeWharton的ViewPagerIndicator时,在CircleIndicator中的onSaveInstanceState()中保存了当前的page信息,于是就学习这块。

介绍:

onSaveInstanceState()是在Activity被异常回收时会被调用,正常情况下不会调用该方法。Activity重建时会调用onRestoreInstanceState()方法,进行恢复数据。 我们在写自定义控件时,如果有必要,则要复写这两个方法。

异常情况有:

资源相关的系统配置发生改变,导致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]; } }; }

另一种写法

@Override protected Parcelable onSaveInstanceState() { Bundle bundle = new Bundle(); bundle.putParcelable("superState", super.onSaveInstanceState()); bundle.putInt("current_item", currentItem); bundle.putStringArray("notifications", notifications); return bundle; } @Override protected void onRestoreInstanceState(Parcelable state) { if (state instanceof Bundle) { Bundle bundle = (Bundle) state; currentItem = bundle.getInt("current_item"); notifications = bundle.getStringArray("notifications"); state = bundle.getParcelable("superState"); } super.onRestoreInstanceState(state); }

Fragment中:

@Override public void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); outState.putParcelable(EXTRA_PARCELABLE, a); }//可获取@Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); }//可获取 @Override public void onActivityCreated(@Nullable Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); }

原理:

当Activity被意外终止,Activity会调用onSaveInstanceState()去保存数据,然后Activity委托Window去保存数据。Window再委托它上面的顶级容器去保存数据。顶层容器是一个ViewGroup,通过他再去一一通知它的子元素来保存数据。

这篇文章 Saving Android View state correctly 更加精细的讲解了这个过程。

保存数据的条件:

必须要有ID。因为底层通过sparseArray保存数据,ViewId作为key存在。ViewId必要要独立。unique。所有状态都保存在一个sparseArray中,相同的id会造成覆盖。

参考:

能极大促进理解: Saving Android View state correctly

自定义控件中SaveState写法: stackoverflow


发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表