Activity重建之殇

很多时候,对于一些初学者来说,activity的重建是很痛苦的,面对网络上众多的说法,我们无从下手,无从做起。

其实很多时候只要我们掌握了其中的必要方法,就能解决大部分的activity的重建问题。下面我就来总结一下activity重建的一些必要方法,以及列举几点常见的问题。

1. Activity何时需要重建

activity的销毁:

正常:正常情况下的销毁,比如用户按下Back按钮或者是activity自己调用了finish()方法

异常:异常情况下的销毁,或者出现内存不足的情况下而销毁。简单来说就是在“未经许可”的情况下被销毁了

异常销毁后,Activity会重新创建一个新的对象,而不再是以前的Activity

2. 如何重建

onSaveInstanceState()方法的覆写

为什么?

Android应用框架中定义的几乎所有UI控件都恰当的实现了onSaveInstanceState()方法, 因此当activity被摧毁和重建时, 这些UI控件会自动保存和恢复状态数据

但是很多时候我们需要保存更多的数据才能满足我们的重建,这时候我们就可以覆写onSaveInstanceState()方法保存一些保存瞬态数据,比如成员变量等。

当Activity在非正常情况下销毁时,会在onPause或onStop方法之前调用onSaveInstanceState方法,正常情况下不会调用

@Overrideprotected void onSaveInstanceState(Bundle outState) {super.onSaveInstanceState(outState);outState.putString("testStr", mString);outState.putInt("testInt", mInt);}

恢复Activity的状态

当Activity被销毁后要重建时,可以从onSaveInstanceState方法中保存的Bundle对象中恢复数据。onCreate()和onRestoreInstanceState()两个方法的Bundle对象保存的数据是一样的。

    @Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);if (savedInstanceState != null) {mString = savedInstanceState.getString("testStr");mInt = savedInstanceState.getInt("testInt");}}

或者使用onRestoreInstanceState,只有在Activity重建恢复数据时才会调用onRestoreInstanceState方法,正常情况下不会调用,所以不需要判断Bundle是否为空

@Overrideprotected void onRestoreInstanceState(Bundle savedInstanceState) {super.onRestoreInstanceState(savedInstanceState);mString = savedInstanceState.getString("testStr");mInt = savedInstanceState.getInt("testInt");}

3. Fragment如何重建

Fragment重建跟Activity重建大同小异,方法差不多,下面是我在Fragment重建过程中遇到的一些问题:

  1. Activity销毁前hide的Fragment在重建之后全部出现

    原因:
    经过项目应用跟自己写的demo测试发现,在Activity销毁之前hide到栈中的Fragment在重建之后mHidden全部为false,也就是说隐藏的Fragment不再隐藏,所以我们就看到了全部展现出来的样子
    解决办法:
    通过Activity或者其所在的父Fragment管理控制Fragment隐藏,但由于无法知道Activity重建时Fragment何时重建好,所以目前的做法是在Activity中监听Fragment是否重建好了

  1. Fragment重建之后出现重叠(出现两个相同的Fragment)

    原因:
    由于Activity重建的几率比较小,所以很多开发者可能不会注意到Fragment重建后出现的问题。一般情况下,Fragment的创建都是在Activity的onCreate或onStart里面,当Activity重建时导致再次创建了Fragment,而重建的Fragment也出现了,所以就出现了重叠。

    解决办法:
    复用重建的Fragment或者删掉重建的重新创建:

  1. 重建的Fragment上面的item无法点击

    原因:
    原因很简单,如果listener是从别的地方传进来的,当Fragment重建时如果没有保存listener,必然的会无法监听点击事件

    解决办法:
    目前想到的方法有两种:

    1. 在前面所说的那个监听Fragment重建完成的回调里传listener进去
    2. 在onAttach方法里面把Activity强制转化为listener

  1. 重建的特殊的Fragment状态异常

    原因:
    提出这个状态异常主要是针对项目里遇到的滑块无法滑动的问题。原因是Fragment重建时需要重新走一遍onBindViewHolder,所以通过findViewHolderAdaterByPosition是无法找到数据的

    解决办法:
    通过前面说的onSaveInstanceState方法保存position,在onBindViewHolder时恢复状态

4. 建议及注意事项

一般情况下很难复现Activity销毁的情况,如果我们要测试可以通过开启“不保留活动”,如图:

如果不需要重建Activity或者Activity里面装载的Fragment比较多,要恢复到原来的状态比较困难,可以重写Activity或Fragment的onSaveInstanceState方法,如图:

5. Commit与commitAllowingStateLoss的区别:

在这里我觉得还有必要补充一下commit和commitAllowingStateLoss的区别:

commit方法和commitAllowingStateLoss方法,都同时调用了commitInternal方法,只是传的参数略有不同

在对 commit和commitAllowingStateLoss的传参进行判断后,将任务扔进activity的线程队列中。这个两个方法区别就在传参判断后的处理方法checkStateLoss

当使用commit方法时,系统将进行状态判断,如果状态(mStateSaved)已经保存,将发生”Can not perform this action after onSaveInstanceState”错误。如果mNoTransactionsBecause已经存在,将发生”Can not perform this action inside of ” + mNoTransactionsBecause错误

避免异常抛出的最优方法就是避免在异步回调方法中调用commit

以上就是我对activity重建的一些见解,希望对大家有帮助,如有写得不对的地方,欢迎指出。

Activity重建之殇相关推荐

  1. Android旋转屏幕时阻止activity重建

    Android在旋转屏幕时activity会被重建,重新调用activity的各个生命周期,如果不想重建,那么需做如下设置: android:configChanges="orientati ...

  2. 屏幕旋转导致Activity销毁重建,ViewModel是如何恢复数据的

    前言 当屏幕旋转或者切换系统语言时,Activity 生命周期从销毁再重建,但是ViewModel里面的变量值不受到影响,说明ViewModel中的变量在屏幕旋转前进行了存储,在屏幕旋转后又进行了恢复 ...

  3. activity直接销毁_Android -- Activity的销毁和重建

    两种销毁 第一种是正常的销毁,比如用户按下Back按钮或者是activity自己调用了finish()方法: 另一种是由于activity处于stopped状态,并且它长期未被使用,或者前台的acti ...

  4. Activity的重建(recreate)与恢复

    关于Activity的重建我们可以从以下三个方面去了解: Activity会出现重建的三种情况: 1. 系统内存不足:android系统会杀死一个进程,在系统需要释放内存的时候,而位于进程内的acti ...

  5. Android 面试题:为什么 Activity 都重建了 ViewModel 还存在?

    作者:彭旭锐 链接:https://juejin.cn/post/7121998366103306254 前言 ViewModel 是 Jetpack 组件中较常用的组件之一,也是实现 MVVM 模式 ...

  6. activity 启动模式_腾讯大牛:你根本不懂Activity!

    码个蛋(codeegg)第 583 次推文 作者:厘米姑娘 原文:https://www.jianshu.com/p/602b1ec4ca7a 在之前的Activity篇主要学习Activity的生命 ...

  7. 基础总结篇之一:Activity生命周期

    子曰:溫故而知新,可以為師矣.<論語> 学习技术也一样,对于技术文档或者经典的技术书籍来说,指望看一遍就完全掌握,那基本不大可能,所以我们需要经常回过头再仔细研读几遍,以领悟到作者的思想精 ...

  8. Android 屏幕旋转时Activity的变化

    Android开发文档上专门有一小节解释这个问题.简单来说,Activity是负责与用户交互的最主要机制,任何"设置"(Configuration)的改变都可能对Activity的 ...

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

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

  10. activity 变成后台进程后被杀死_Android后台杀死系列之二:ActivityManagerService与App现场恢复机制...

    本篇是Android后台杀死系列的第二篇,主要讲解ActivityMangerService是如何恢复被后台杀死的进程的(基于4.3 ),在开篇FragmentActivity及PhoneWindow ...

最新文章

  1. 陪伴程序员的一条龙、一骑士 36 岁了!
  2. python异常处理优点_python自测100题(下)
  3. 「2019 嵌入式智能国际大会」 399 元超值学生票来啦,帮你豪省 2600 元!
  4. 微信公众平台开发(41)一键关注微信公众平台账号
  5. pymysql断开连接怎么办
  6. android 获得资源图片,快速获取app(ios和安卓)资源图片
  7. Talkfree7手机电视,IPTV,VOIP-GPS-3G手机,WAP是未来
  8. 从PowerDesigner概念设计模型(CDM)中的3种实体关系说起
  9. ADSL自动更换IP的方法
  10. spring boot电影院售票与管理系统 毕业设计源码论文+答辩PPT
  11. 开往-友链接力handsome侧栏添加修改
  12. FusionAccess桌面云
  13. [MFC] CList
  14. 计算机本科毕业设计-智能分类垃圾桶
  15. 图像处理入门和UltraLAB P620系列全能型、高性能、静音级便携工作站
  16. 30个后台管理系统模板
  17. 免费使用谷歌的深度学习云服务
  18. 翻译翻译,什么是CAP
  19. 操作系统学习笔记-虚拟内存
  20. Yahoo! 搜索引擎顶级使用技巧

热门文章

  1. 块存储、文件存储、对象存储三者的区别
  2. 【LOJ2542】【PKUWC2018】—随机游走(Min-Max容斥+树形dp+FMT)
  3. linux系统外接硬盘_电脑主硬盘linux系统,外接硬盘win7系统.如何启动外接硬盘的win7系统?...
  4. 京东单号中转延误如何查询出的方法
  5. flutter仿ReadHub+
  6. 一生至少原谅的三个人
  7. Vue实现页面导航实战
  8. linux添加mx记录,linux下nslookup操作实例,查找域名的a记录、mx记录、cname记录、ns记录...
  9. java获取域名的mx记录,A记录、CNAME、MX记录、NS记录
  10. 摸鱼小组-冲刺日志(第二天)