关闭

android activity 应该知道的一切(完整篇)

标签: androidactivity生命周期
682人阅读 评论(0) 收藏 举报
分类:

概述

前面讲解了关于activity生命周期的一些基本知识,不了解的看前面这篇文章 ,其中onPause方法也单独特别讲解过,当另一个activity启动,覆盖到当前activity上时,当前activity会先执行onPause方法,随后,另一个activity执行onCreate,onStart,onResume方法,然后,当前activity才执行onSaveInstanceState以及onStop,那么这里的顺序可以看出来,onPause的执行时间,会直接影响后者activity的启动时间。所以,这里我们要针对activity的各个生命周期,应该做的事情,做一个梳理和讲解。

onCreate()

这个生命周期方法,在activity正常生命周期的情况下,创建的时候执行一次,此后,都不再执行,鉴于这种情况,在activity生命周期内,只需要初始化一次的变量,可以在这个方法中初始化,例如findviewbyid,这个方法放在其他生命周期中都不合适,因为没有必要反复执行.

onStart()

这个生命周期的执行,代表界面可见了,其实这里也不一定正确,如果你得activity是接受到锁屏相关广播起来的,那么,你前面可能还有锁屏界面,这个生命周期方法和onResume不同的地方在于,如果activity开启了另一个不完全覆盖的activity B,而再次关闭这个B的时候,将不会执行这个方法,但是会执行onResume。也就是说,onstart在每次变得可见的时候才会执行一次,如果有一些动画,在半遮蔽的情况下,也需要播放,那么这里开始播放是一个很好的时机,可以在后面的onStop的停止调用中,成对使用。

同时,可以在onStart中检测一些必要的初始化条件,例如gps是否可用,如果不可用,我们可以提示用户设置,要设置gps,一般会离开这个页面,再次回来的时候,必定还会调用onStart,我们就可以再做检测,如果可用,我们便可以执行其他操作了,如果检测行为放到onresume中,是不合适的,因为开启一个半遮挡的activity,并不能设置gps(一般情况下,设置界面都是完全覆盖的),那么在关闭半遮挡的acitivty的时候,onresum中的检测就显得多余了。

onResume()

这个方法,在activity获得焦点的时候执行,之后用户就可以和activity进行交互了,其实activity真正的可见点是onWindowFocusChanged方法的执行,就如前面所讲,onstart的执行并不能标志可见,因为前面可能还有锁屏,甚至黑屏状态。onWindowFocusChanged一般会在onresum之后或者onpause之后执行。

正如前面分析的,onResume有这样的特殊性,就是在失去交互能力的时候就会回调,那么那些和交互强相关的,就需要在这里初始化了,例如相机的资源的申请,一些强交互的动画的开始等等。这里之所以不再onStart中执行的原因,有部分是这些资源与用户交互关联性强,即使是可见,但是不可交互的情况下,继续运行也没有意义,只会浪费资源,另一部分原因,要看下面的onPause生命周期方法的分析。

onPause()

从上一篇文章可以看到,activity A和B中,如果从A中启动B,那么,首先会执行A的onPause方法,随后会执行B的onCreate,onStart,onResume,然后是A的onSaveInstanceState,onStop。

从上面的生命周期执行顺序可以看到,A中的onPause和onStop并没有紧挨着执行,而是先启动了B,这里主要是为了让B可以快速启动,毕竟这是用户希望看到和交互的页面,那么既然如此,A的onPause方法至关重要,重要的原因有两点:

  1. onPause是释放资源的最佳时机
  2. onPause方法的执行时间会直接影响B的启动流畅度

基于上面两点,以及在前面onResume方法中我们的剖析,在onPause中,我们应该关闭不需要的动画,因为用户很可能即将看不到A页面,没必要播放,同时,需要释放一些独占资源,类似相机,如果在B中,也需要使用相机,那么在他即将执行的几个生命周期方法中,将无法申请到相机权限。

但是onPuase虽然重要,却也不能执行耗时过长的动作,例如用户编辑的文本,需要保存,或者一些需要持久化的统计信息,这类信息,不适合在onPause中执行,他会拉长onPuase的时间,从而影响B的启动。

同时底层执行Activity A的onPause()时,有一定的时间限制的,当ActivityManagerService通知应用进程暂停指定的Activity时,如果对应的onPause()在500ms内还没有执行完,ActivityManagerService就会强制关闭这个Activity。如下就是对应的onPause()执行超时常量定义:

// How long we wait until giving up on the last activity to pause.

//This is short because it directly impacts the responsiveness of startingthe

// next activity.

static final int PAUSE_TIMEOUT = 500; // 定义在ActivityStack.java中

onStop()

在onStop中,可以执行一些稍微重量一点的任务,例如上面说的,用户编辑草稿的保存,一些统计数据的保存,或者另一些业务逻辑。例如在锁屏app中的左划后,需要启动一个Activity B,这里,需要在左划之后做两个操作

一是左划之后,需要统计用户左划的时间等
二是需要左划以后,需要触发一个拉取广告的行为

那么如上两个操作,都不适合在onpause中来执行,这回直接影响B的启动时间,在onStop中要合适得多。同时,一些广播接收者的注销,可以在这里执行,前提是,它接收的广播并不频繁,在onPause和onStop之间的B启动时,被调用的可能性不大的情况下,例如监听系统中app的安装,可以延迟到onStop中执行,以便提升B的启动速度,如果这个广播,例如下载进度的应用内广播,无时无刻不在回调和更新ui,这种情况下,在onStop中注销是无法容忍的,因为在onPause之后的B的启动过程中,它将被多次调用,严重影响性能。

onDestroy()

activity在销毁前会执行的生命周期方法,这个方法执行后,activity就可能会被回收了。在onDestory中可以释放一些变量,特别是在onCreate中初始化,行进在整个生命周期内的变量

例如:bitmap,bitmap的回收一直是android的一大问题,他的反复创建又比较耗费性能,如果在onStart中来创建,在onStop中来回收也不理想,如果这个页面需要经常切换,反而造成内存抖动,这种情况下,可以选择一直持有,在onDestroy中调用bitmap的recycle方法来回收。

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:63749次
    • 积分:907
    • 等级:
    • 排名:千里之外
    • 原创:26篇
    • 转载:4篇
    • 译文:0篇
    • 评论:20条
    博客专栏
    最新评论