Android Activity生命周期管理[通俗易懂]

Android Activity生命周期管理[通俗易懂]AndroidActivity生命周期管理 田海立@CSDN2011/07/23 本文描述Android中Activity的状态,Activity的状态转换,从而总结了Activity各个生命周期的典型时序。与Android现有框架结合,充分考虑Activity的各个生命周期阶段,应用开发者实现相应的回调接口,只有这样,才能开发出符合框架规范的程序。 Activity状态Activity在And

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

Android Activity生命周期管理

 

田海立@CSDN

2011/07/23

 

本文描述Android中Activity的状态,Activity的状态转换,从而总结了Activity各个生命周期的典型时序。与Android现有框架结合,充分考虑Activity的各个生命周期阶段,应用开发者实现相应的回调接口,只有这样,才能开发出符合框架规范的程序。

 

Activity状态

Activity在Android系统中用一个LIFO机制的Activity栈来管理。当新的Activity[A]启动时,它就被放在了Activity栈的顶端,而进入运行状态,而先前运行的Activity[B]通常就被放在了Activity栈里A的下面。当A退出运行而从Activity栈顶出栈之后,B就成了Activty栈的最上面的Activity,可再次进入前台运行状态。

Activity有三种状态

Ø RESUMED当Activity在屏幕前台运行时(位于当前任务堆栈的顶部),此时该Activity获得了用户的输入焦点。 这个状态也叫Active或Running状态。

Ø PAUSED当它失去焦点但仍然对用户可见时,它处于暂停状态。此时,在它之上有另外一个Activity。这个Activity也许是透明的,或者未能完全遮蔽全屏,所以被暂停的Activity仍对用户可见。暂停的Activity仍然是存活状态(它保留着所有的状态和成员信息并连接至窗口管理器)。但当系统处于极低内存的情况下,仍然可以杀死这个Activity。

Ø STOPPED 如果它完全被另一个Activity覆盖是,它处于停止状态。它仍然保留所有的状态和成员信息。然而它不在为用户可见,所以它的窗口将被隐藏。如果其它地方需要内存,则系统经常会杀死这个Activity。

处于PAUSED或STOPPED状态的Activity,可以被移除出内存,移除的先后顺序是先STOPPED状态的,后PAUSED状态的。一般PAUSED状态的Activity也只是在资源极端不足的情况下,它所运行的进程才会被杀掉。是否要移除出内存,还要看它所运行的进程具体状况,具体规则和操作,可参阅[5]。

 

生命周期转换图

下图是根据Android官方提供的Activity状态转换图经过笔者少许更改之后的图。(注意图中,方框内执行的是状态转换的过程,并不是状态,状态如前述,只有三种:RUNNING / PAUSED / STOPPED。在很多文章的描述中,连这点基本的概念都没搞清楚!

Android Activity生命周期管理[通俗易懂]

(现在可以不理解,但是读完全文,一定要把这张图刻到脑子里!)

 

在上图中,可以从三个阶段关注Activity的生命周期: 

Ø  整个的生命周期,指的是onCreate(Bundle)和onDestroy()之间过程。Activity在onCreate()设置所有的“全局”状态,在onDestroy()释放所有的资源。

Ø 可见的生命周期,指的是onStart()onStop()之间的过程。在这段时间,可以看到Activity在屏幕上,尽管有可能不在前台,不能和用户交互。在这两个接口之间,需要保持显示给用户的UI数据和资源等。onStart()onStop()都可以被多次调用,因为Activity随时可以在可见和隐藏之间转换。

Ø 前台的生命周期,指的是onResume()onPause()之间的过程。在这段时间里,该Activity处于所有 Activity的最上面,获得了用户焦点。Activity可以经常性地在RESUMED和PAUSED状态之间切换,所以在这些接口方法中的代码应该属于非常轻量级的,避免低效的转换而让用户有等待的感觉。

 

由此,我们可以得出下面几个典型的场景

1)   Activity从被装载到运行。则执行顺序为:onCreate() -> onStart()-> onResume();

这是个典型过程,发生在Activity被系统装载运行时。

2)   Activity从运行到暂停,再到继续回到运行。执行顺序为:onPause() -> onResume();

这个过程发生在Activity被别的Activity遮住了部分UI,失去了用户焦点,另外那个Activity退出之后,这个Activity再次重新获得运行。这个过程中该Activity的实例是一直存在。

3)   Activity从运行到停止。执行顺序为:onPause() -> onStop() ;

这个过程发生在Activity的UI完全被别的Activity遮住了,当然也失去了用户焦点。这个过程中Activity的实例仍然存在。比如,当Activity正在运行时,按HOME键,该Activity就会被执行这个过程。

4)   Activity从停止到运行。执行顺序为:onRestart()-> onStart()-> onResume();

处于STOPPED状态并且实例仍然存在的Activity,再次被系统运行时,执行这个过程。这个过程是3的逆过程,只是要先执行onRestart()而重新获得执行。

5)   Activity从运行到销毁。执行顺序为:onPause() -> onStop() -> onDestroy();

这个过程发生在Activity完全停掉并被销毁了,所以该Activity的实例也就不存在了。比如,当Activity正在运行时,按BACK键,该Activity就会被执行这个过程。这个过程可看作是1的逆过程。

6)   被清除出内存的Activity重新运行。执行顺序为:onCreate() -> onStart()-> onResume();

这个过程对用户是透明的,用户并不会知道这个过程的发生,看起来如同1的执行顺序,不同的是如果保存有系统被清除出内出时的信息,会在调用onCreate()时,系统以参数的形式给出,而1中onCreate()的参数为null。

 

管理Activity生命周期

这里说是管理Activity的生命周期,更确切的说应该是参与生命周期的管理,因为Android系统框架已经很好的管理了这其中的绝大部分,应用开发者要做的就是在Android的框架下,在Activity状态转换的各个时点上,做出自己的实现,而实现这些要做的只是在你的Activity子类里面Override这些Activity的方法即可。

下图是Activity生命周期相关的方法。

Android Activity生命周期管理[通俗易懂]

Activity的实例化与启动

Activity实例化是由Android系统完成,在用户点击执行一个Activity或者另一个Activity需要这个Activity执行的时候,如果该Activity的实例不存在,Android系统都会实例化之,并在该Activity所在进程的主线程中调用该Activity的onCreate()方法,实现Activity实例化时的工作。

所以,Activity::onCreate()是系统实例化Activity时,Activity可做的自身初始化的时机。在这里可以实例化变量,调用Activity::setContentView()设置UI显示内容。

一般的,Activity实例化之后,就要启动该Activity,这样会在该Activity所在进程的主线程中顺序调用Activity的onStart()onResume()。回头看图一Activity的生命周期的典型时序,一般onStart()在所有的时序中都不是很特别的过程,所以一般不怎么实现。onResume()在暂停继续流程中很重要,后文再讲。

 

下图就是Activity实例化与启动的时序

Android Activity生命周期管理[通俗易懂]

这里从应用开发者角度来说明问题,暂不考虑Android内部的实现细节,所以各种动作的发起者统一用AndroidSystem来说明,而从Activity这边看过去,所有这些操作也都是异步的。

 

注意

onCreate()在Activity存续期内,只会被调用一次。如生命周期图中的时序6的情形其实是另外又启动了一个Activity的实例,并通过onCreate()的参数传递进先前杀掉的Activtiy里保留的信息。

onStart()可因为已经STOPPED了,再次执行而被调用多次。

onResume()可因为Activity的PAUSED/RESUMED的不停转换,而被频繁调用。

 

Activity的暂停与继续

Activity因为被别的Activity遮住部分UI,并失去焦点而被打断暂停,典型的情况发生在系统进入睡眠或被一个对话框打断的情况。而在被暂停之前,系统会通过onPause()让Activity有保留被暂停前状态的时机。Activity可以在onPause()中,保存所做的修改到永久存储区,停止动画显示,等。onPause()里的操作必须简短并快速返回,因为在onPause()返回之前不会调入其他的Activity运行。

此时Activity因为还有部分UI显示,它通常与Window Manager的链接还在,所以一般UI的修改不需保留。即便在极端的情况下,PAUSED的Activity所在的进程被杀死,那也是极端情况,那种情况下,不可能使Activity的UI显示完整一致。

系统在被唤醒或者打断它的对话框消失之后,会继续运行,此时系统会调用Activity的onResume()方法。在onResume()方法中可以做与onPause()中相对应的事情。

下图是,一个Activity启动同一个进程内另外一个Activity的时序图。它能很好的说明,一个Activity启动时,与另外一个Activity之间的各种PAUSE/RESUME交互过程。

Android Activity生命周期管理[通俗易懂]

不过千万记得,PAUSE/RESUME是众多Activity状态转换中的一个子集,很多其他的场景也是要走这个过程的。

 

Activity的关闭/销毁与重新运行

Activity被STOP可能是完全被别的Activity覆盖掉了,也可能是用户显式的按了BACK或HOME键。Activity被Stop之前,它的onStop()方法会被提前调用,来做些Stop前的处理。如果处于STOPPED的Activity再次运行,它的onRestart()方法会被调用,这是区分其他调用场景,比较合适的实现处理的地方。

注意,因为处于PAUSED状态的Activity在内存极端不足的情况下,它所在的进程也可能被杀掉,这样onStop()在被杀掉前,不一定会被调用,所以onPause()是比onStop()更合适的保留信息到永久存储区的时机。

Activity被销毁可能是显式的按了BACK键,也可能是处于PAUSED或STOPPED状态,因为内存不足而被杀掉的。还有种情况是配置信息改变(比如屏的方向改变)之后,根据设置需要杀掉所有的Activity(是否关闭还要看Activity自己的配置),再重新运行他们。

被系统隐式杀死的Activity,在被杀死(onStop()调用)之前,一般的会调用onSaveInstanceState()保留该Activity此时的状态信息。该方法中传入Bundle参数,可在此方法中把此时的状态信息写入,系统保留这这些系统。而当该Activty再次被实例化运行时,系统会把保留在Bundler的信息再次以参数形式,通过onCreate()方法传入。

一般,onSaveInstanceState()中保留UI的信息,永久存储的信息最好还是在onPause()中保存。Activity的onSaveInstanceState()已经缺省实现来保留通用View的UI信息,所以不管你保留与否当前Activity的信息,通常都要在onSaveInstanceState()先调用一下super.onSaveInstanceState()保留通用的UI信息。

 

参考资料及进一步阅读

[1] DeveloperGuide Framework Topics – Activities http://developer.android.com/guide/topics/fundamentals/activities.html

[2] ActivityReference http://developer.android.com/reference/android/app/Activity.html

[3] Activitysources Activity.java

[4] Intentand Intent filters http://developer.android.com/guide/topics/intents/intents-filters.html

[5] Processesand Threads http://developer.android.com/guide/topics/fundamentals/processes-and-threads.html

 

 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/170687.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • matlab批量处理excel(CSV)文件数据

    matlab批量处理excel(CSV)文件数据今天是2019-1-29,参加完2019年美国大学生数学建模竞赛,小伙伴都回家了,就我一个人在寝室,太无聊了,就把在比赛中遇到的excel批处理,写一下思路(ps:其实我在比赛中利用的是SQLServer数据库和matlab相结合的数据处理方法,但是一般情况下遇到的都是matlab对excel数据批处理,所以降低要求写了matlab对exc…

    2022年6月28日
    26
  • python求解中位数、均值、众数

    python求解中位数、均值、众数首先定义一个数据,在这里我假定为:num=[2,3,2,5,1,0,1,2,9]一、求中位数    中位数(又称中值,英语:Median),统计学中的专有名词,代表一个样本、种群或概率分布中的一个数值,其可将数值集合划分为相等的上下两部分。对于有限的数集,可以通过把所有观察值高低排序后找出正中间的一个作为中位数。如果观察值有偶数个,则中位数不唯一,通常取最中间的两个数值的平均数…

    2025年12月14日
    4
  • unityshader教程_unity炫酷的shader

    unityshader教程_unity炫酷的shader参考链接:http://www.xiaobao1993.com/373.html去色shader:Shader”Custom/Gray”{ Properties { _MainTex(“Base(RGB)”,2D)=”white”{} }SubShader{Pass{C

    2022年10月5日
    3
  • CSS设置背景颜色透明

    CSS设置背景颜色透明CSS设置背景颜色透明将背景颜色设置为透明,两种方法:方法一:通过background-color和opacity来设置opacity属性参数的不透明度是以数字表示的,从0.0到1.0,完全透明是0.0,完全不透明是1.0,数字越大代表元素越不透明。<divclass=”box01″><p>今天星期三</p></div><divclass=”box02″><p>和上面盒子对比</p

    2022年6月20日
    62
  • db2事务隔离级别设置_db2存储过程

    db2事务隔离级别设置_db2存储过程Jdbc事务隔离级别 Jdbc隔离级别 数据库隔离级别 数据访问情况 TRANSACTION_READ_UNCOMMITTED(未提交读)UncommittedRead ur 脏读,在没有提交数据的时候能够读到已经更新的数据 TRANSACTION_READ_C…

    2022年10月14日
    4
  • 深度学习之softmax损失函数[通俗易懂]

    深度学习之softmax损失函数[通俗易懂]深度学习之softmax损失函数归一化向量的每个元素均大于0小于1,且和为1,所以可以将其看作归属各个类别的概率。损失函数可以看作真实类别的负对数概率,希望其越小。importnumpyasnpD=784K=10N=128#scores是分值矩阵,每行代表一个样本scores=np.random.randn(N,K)print(scores.shape)#样本标签y=np.random.randint(K,size=N)print(y.shape)#指数化分值矩

    2022年6月26日
    35

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号