自定义控件基础 onSaveInstanceState()
2016-03-30 13:19
435 查看
在看JakeWharton的ViewPagerIndicator时,在CircleIndicator中的onSaveInstanceState()中保存了当前的page信息,于是就学习这块。
我们在写自定义控件时,如果有必要,则要复写这两个方法。
异常情况有:
资源相关的系统配置发生改变,导致Activity被杀死并重新创建。比如旋转屏幕等。
系统资源内存不足导致低优先级的Activity被杀死。
这种写法也是自定义控件时标准写法。具体可查看文章底部链接。 可以查看TextView源码,这块也是这样写的。
这篇文章 Saving Android View state correctly 更加精细的讲解了这个过程。
保存数据的条件:
必须要有ID。因为底层通过sparseArray保存数据,ViewId作为key存在。
ViewId必要要独立。unique。所有状态都保存在一个sparseArray中,相同的id会造成覆盖。
参考:
能极大促进理解:
Saving Android View state correctly
自定义控件中SaveState写法:
stackoverflow
介绍:
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); }
原理:
当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
相关文章推荐
- 平均值滤波之经典形式改进
- sudo 权限问题
- win10重置无线网
- 30.leetcode题目104: Maximum Depth of Binary Tree(递归,深度优先)
- 解决软键盘对fixed的影响
- Linux进程管理之“四大名捕”
- 解决ListView在ScrollView中滑动冲突
- Redis持久化
- hdoj 1878 欧拉回路 (并查集+欧拉)
- 高仿京东APP首页“京东快报”自动向上滚动的广告条
- Linux资源
- COM 类工厂中 CLSID 为 {000209FF-0000-0000-C000-000000000046} 的组件失败,原因是出现以下错误: 80070005 拒绝访问。
- 苹果、微软等外企域名或必须在华注册
- 教你如何查看一款App里面所包含的图片
- 使用PHP创建一个REST API(Create a REST API with PHP)
- hook 学习
- 052(一)
- cf题量突破一百题了
- HDU 2845 Beans
- 关于android.mk文件的作用、语法和自动添加源文件的学习