安卓自定义View的状态保存与恢复

我们在开发某些安卓应用(如安卓小游戏)时,可能会用到自定义View,这时候往往需要保存自定义View的状态信息,以便在遇到某些情况(如由于系统内存资源紧张被系统杀死;或者在平板上经常发生的旋转屏幕)时能够恢复之前的状态信息,不给用户带来不必要的麻烦。
笔者在开发一款安卓平台的人机五子棋时就用到了自定义View,由于需要适配平板,因此要考虑旋转屏幕的情况。首先看一下Activity的生命周期,如下图所示:

从下图可知,翻转屏幕时依次调用了
onPause(),onStop(),onDestroy(),onCreate(),onStart(),onResume()方法来进行当前活动的摧毁和重建。

在这一过程中,安卓会自动完成系统自带的View的状态的保存和恢复,而对于我们的自定义View的状态保存和恢复则需要我们自己来完成。

下面就谈谈如何进行自定义View的状态保存和恢复,主要用到两个方法。onSaveInstanceState()和onRestoreInstanceState(Parcelable state)。
onSaveInstanceState()的源码如下,主要任务是在可序列化对象state中存储需要被保存的信息mStartActivityRequestWho。

@CallSuperprotected Parcelable onSaveInstanceState() {mPrivateFlags |= PFLAG_SAVE_STATE_CALLED;if (mStartActivityRequestWho != null) {BaseSavedState state = new BaseSavedState(AbsSavedState.EMPTY_STATE);state.mStartActivityRequestWhoSaved = mStartActivityRequestWho;return state;}return BaseSavedState.EMPTY_STATE;}

onRestoreInstanceState(Parcelable state)源码如下:主要任务是根据参数state的mStartActivityRequestWhoSaved属性值来得到被保存的信息mStartActivityRequestWho,以便在重建Activity的时候恢复被保存的信息。

@CallSuperprotected void onRestoreInstanceState(Parcelable state) {mPrivateFlags |= PFLAG_SAVE_STATE_CALLED;if (state != null && !(state instanceof AbsSavedState)) {throw new IllegalArgumentException("Wrong state class, expecting View State but "+ "received " + state.getClass().toString() + " instead. This usually happens "+ "when two views of different type have the same id in the same hierarchy. "+ "This view's id is " + ViewDebug.resolveId(mContext, getId()) + ". Make sure "+ "other views do not use the same id.");}if (state != null && state instanceof BaseSavedState) {mStartActivityRequestWho = ((BaseSavedState) state).mStartActivityRequestWhoSaved;}}

下面拿笔者自己写的小游戏五子棋来举个例子。没有重写上述两个方法的效果图如下,当旋转屏幕时,棋盘上的棋子消失了(T . T)

重写方法如下:

    private static final String INSTANCE="instance";//游戏结束与否private static final String INSTANCE_GAME_OVER="instance_game_over";//白棋数组private static final String INSTANCE_WHITE_ARRAY="instance_white_array";//黑棋数组private static final String INSTANCE_BLACK_ARRAY="instance_black_array";//棋盘信息private static String INSTANCE_CHESSBOARD[];//玩家胜利private static final String INSTANCE_MYWIN="instance_mywin";//计算机胜利private static final String INSTANCE_COMPUTERWIN="instance_computerwin";//人机算法参数1private static final String INSTANCE_MS="instance_ms";//人机算法参数2private static final String INSTANCE_CS="instance_cs";@Overrideprotected Parcelable onSaveInstanceState() {//将数据保存在可序列化对象bundle中Bundle bundle=new Bundle();//保存系统原有的其他状态信息                    bundle.putParcelable(INSTANCE,super.onSaveInstanceState());//根据信息数据类型的不同,调用不同方法进行,存储到bundle中bundle.putBoolean(INSTANCE_GAME_OVER,gameOver);bundle.putParcelableArrayList(INSTANCE_WHITE_ARRAY,mWhiteArray);bundle.putParcelableArrayList(INSTANCE_BLACK_ARRAY,mBlackArray);INSTANCE_CHESSBOARD=new String[MAX_LINE];for(int i=0;i<MAX_LINE;i++){INSTANCE_CHESSBOARD[i]="instance_chessboard"+i;bundle.putIntArray(INSTANCE_CHESSBOARD[i],chessBoard[i]);}bundle.putIntArray(INSTANCE_MYWIN,myWin);bundle.putIntArray(INSTANCE_COMPUTERWIN,computerWin);bundle.putIntArray(INSTANCE_MS,ms);bundle.putIntArray(INSTANCE_CS,cs);//返回bundlereturn bundle;}@Overrideprotected void onRestoreInstanceState(Parcelable state) {//判断state的类型是否为bundle,若是则从bundle中取数据if(state instanceof Bundle){Bundle bundle=(Bundle)state;gameOver=bundle.getBoolean(INSTANCE_GAME_OVER);mWhiteArray=bundle.getParcelableArrayList(INSTANCE_WHITE_ARRAY);mBlackArray=bundle.getParcelableArrayList(INSTANCE_BLACK_ARRAY);for(int i=0;i<MAX_LINE;i++){chessBoard[i]=bundle.getIntArray(INSTANCE_CHESSBOARD[i]);}myWin=bundle.getIntArray(INSTANCE_MYWIN);computerWin=bundle.getIntArray(INSTANCE_COMPUTERWIN);ms=bundle.getIntArray(INSTANCE_MS);cs=bundle.getIntArray(INSTANCE_CS);super.onRestoreInstanceState(bundle.getParcelable(INSTANCE));return;}super.onRestoreInstanceState(state);}

现在再来看一下加了上述方法后的运行情况:

最终效果如下:

安卓自定义View的状态保存与恢复相关推荐

  1. Android Fragment使用(三) Activity, Fragment, WebView的状态保存和恢复

    Android中的状态保存和恢复 Android中的状态保存和恢复, 包括Activity和Fragment以及其中View的状态处理. Activity的状态除了其中的View和Fragment的状 ...

  2. android 自动恢复,Android的状态保存和恢复

    Activity的状态保存和恢复 Activity的状态什么时候需要保存和恢复 Activity的销毁一般分为两种情况: 当用户按返回按钮或你的Activity通过调用finish()销毁时,这属于正 ...

  3. 安卓自定义view中 绘画基本图形点线面,矩形,方形,圆,扇形,文字及沿着特定方向布局,自定义圆角ImageView图片等等相关api使用方法及举例

    安卓自定义view中 绘画基本图形点线面,矩形,方形,圆,扇形,文字及沿着特定方向布局,自定义圆角ImageView图片等等相关api使用方法及举例,图片压缩处理逻辑 本文旨在介绍自定义View的实现 ...

  4. 安卓自定义View——网易颜色渐变效果指示器

    一直想写博客来着,可惜直到现在才真正抽出时间.最近一直在研究网易新闻这个UI框架,发现了一些很值得借鉴的效果,当然,网上也不乏这方面的介绍.本文主要实现的指示器效果为字体颜色和大小渐变,废话不多说献上 ...

  5. 安卓自定义View进阶-事件分发机制原理

    之前讲解了很多与View绘图相关的知识,你可以在 安卓自定义View教程目录 中查看到这些文章,如果你理解了这些文章,那么至少2D绘图部分不是难题了,大部分的需求都能满足,但是关于View还有很多知识 ...

  6. QPainter 的状态保存与恢复

    实现这样的一个程序,把 QPainter 的坐标原点从左上角移动到 (100, 100),然后画出坐标轴,接下来顺时针旋转坐标轴 45 度,设置画笔,画刷,字体,画一个矩形和字符串,最后恢复 QPai ...

  7. 安卓自定义view全解:初始化,onDraw函数,onMeasure函数,用户手势事件

    全栈工程师开发手册 (作者:栾鹏) 安卓教程全解 安卓自定义view全解. view类包含如下函数.可供重写. onFinishInflate() 回调方法,当应用从XML加载该组件并用它构建界面之后 ...

  8. android控件向内弧度_安卓自定义 View 基础:坐标系、角度弧度、颜色

    安卓自定义View基础 - 坐标系 一.屏幕坐标系和数学坐标系的区别 由于移动设备一般定义屏幕左上角为坐标原点,向右为x轴增大方向,向下为y轴增大方向, 所以在手机屏幕上的坐标系与数学中常见的坐标系是 ...

  9. 安卓自定义View实现加载gif图片

    开题:加载GIF的场景在安卓开发中还比较常见,网上也有一些三方法的框架会支持对gif的加载,在上篇博客为大家推荐的图片加载库Glide也支持gif的加载Glide工具类的简单封装,今天给大家分享通过自 ...

最新文章

  1. 计算机控制系统如何设计,计算机控制系统设计
  2. 弹性地基梁板法计算原理_地基下沉别慌张!沉着冷静用对地基加固法
  3. linux下tomcat部署
  4. C# WinForm程序退出的方法
  5. flowable 集成mongodb
  6. type=radio增加onclick没有效果_佳能6d+小痰盂镜头,加1张餐巾纸拍摄花卉,朦胧美效果你喜欢吗?...
  7. SQLi LABS Less 16 布尔盲注
  8. 第二章:在HTML中使用JavaScript
  9. 阶段3 1.Mybatis_11.Mybatis的缓存_5 缓存的概念
  10. tomcat/redis/dubbo/netty
  11. 数据结构——线段树学习笔记
  12. atom n270 cpu linux,继续改造ATOM N270增加千兆口自制软路由
  13. 【软件构造】正则表达式合法性检测
  14. 【报告分享】头部DTC品牌增长案例库-易观智库零一裂变(附下载)
  15. android 适配红米,小米MIUI放出Android Q适配计划,11款手机参与,包括红米Note 7
  16. 陀螺产业区块链第十五季 | 博雅正链RegChain
  17. Codeforces 1247D. Power Products (logn质因数分解)
  18. [转]Windows Shell 编程 第十章
  19. xcode提交app时出现icon缺少167.png图片的问题
  20. 解决usage: mo_onnx.py [options] mo_onnx.py: error: unrecognized arguments: 113.985 119.85] 69.87 70.89

热门文章

  1. html5位图图像,LEADTOOLS HTML5图像教程
  2. 商场里的店,为何三年换一波?
  3. 知识图谱之《海贼王-ONEPICE》领域图谱项目实战(含码源):数据采集、知识存储、知识抽取、知识计算、知识应用、图谱可视化、问答系统(KBQA)等
  4. 黑谍旺旺群发V3.11绿色注册版
  5. python绘制樱花洒落_用python绘制樱花树
  6. html5 公众号 网站,编辑公众号最实用的三个网站
  7. 【C++核心编程】4.4类和对象:友元
  8. English——从句中的虚拟语气
  9. iOS 微博 sdk app私信推荐
  10. 2022年私域迎来第二次浪潮,一定要看懂这几大趋势