Activit系列之---Activity的生命周期

Activity的生命周期

Hello,巴友们好,小菜我又来发博文啦。上篇文章给大家简单的介绍了一下Activity,以及如何创建一个最简单的Activity并且在上面显示hello android!

我们知道要创建一个自己的Activity就必须继承Activity这个类,并且实现它的回调方法,以便Activity在本身的生命周期中的两个不同状态切换时供系统调用。

那什么是Activity的生命周期呢?Activity的生命周期有哪些呢?什么时回调方法呢?今天我们就来回答这3个问题。

首先我们先看看google官方给出的Activity生命周期的图。

这张图中包含了Activity的所有生命周期,已经它们改变时的条件。

Activity的生命周期包括:

  1. onCreate()
  2. onStart()
  3. onResume()
  4. onPause()
  5. onStop()
  6. onRestart()
  7. onDestroy()

这7个方法就是Activity的生命周期,也是回调方法。为什么这么说呢?我们在了解Activity的生命周期时一定要有一个这样的概念:“是操作系统在调用我们,而不是我们在调用操作系统”也就是说操作系统已经定义好了Activity的各种生命状态的点,我们要做的只是在不同的生命周期完成不同的操作就可以了。就了这个概念就不难理解为什么这7个方法又称为回调方法了。

  那这些方法是什么时候被系统调用?又是什么时候结束的呢?

从上图中我们可以看见,activity启动之后,就会运行:

OnCreate()-àonStart()-àonResume()方法

当另外一个Activity被启动时,旧的Activity会调用:

OnPause()-àonStop()方法

这时候旧的Activity会继续在后台运行,除非系统资源不够用了,操作系统才会销毁这些不可见的Activity.

如果旧的Activity重新开始在前台运行就会调用:

OnRestart()-àonStart()-àonResume()方法

直到退出该Activity才会调用:onDestroy()方法。

现在我们就对这7个方法的运行条件进行单个的分析。

  1. onCreate():当Activity第1次启动时才调用。如果该Activity是第2次调用则不会运行onCreate方法,而直接运行onStart()方法。比如启动了一个新的Activity,旧的Activity转入了后台,当旧的Activity在前台再次运行时就不会再执行onCreate()方法了。由于这个特性,一般可以在onCreate()方法中初始化一些只需要初始化一次的变量,当然这都不是固定的,你可以根据你的业务需求来决定。
  2. onStart():当这个Activity对用户可见之前被调用。基本上onCreate()方法和onRestart()方法后面总是伴随着onStart()方法,反之则不成立。
  3. onResume():当Activity能够被用户看见的时候被调用。
  4. onPause():当另外一个新的Activity启动时,首先会调用旧的Activity的onPause()方法。值得注意的是,在Android系统中,Activity并不一定会充满整个屏幕,这是由Activity的样式决定的,如果新的Activity并没有充满整个屏幕,那么旧的Activity依然是可见的,只是背景会变为半透明。这种情况下,系统是不会调用旧Activity的onStop()方法的,并且在新的Activity结束之后只调用旧Activity的onResume()方法。还要注意的是,从API上我们可以看到在onPause(),onStop(),onDestroy()这三个状态时进程是有可能被系统给kill掉的。在进程被系统kill掉之前onPause()是唯一保证能够被调用的方法,因为在需要紧急释放内存的情况下onStop(),onDestroy()方法可能不会被调用。因此我们应该在onPause()方法中保存我们的持久性数据。但是我们应该有选择性的在onPause()方法里添加操作,因为如果onPause()方法执行的时间过长,将会影响到新Activity的启动。导致用户体验下降。
  5. onStop():当然大多数情况下,新的Activity总会充满整个屏幕,这就意味着旧的Activity将不可见。当旧的Activity不可见时,就会调用onStop()方法了。
  6. onRestart():当新的Activity充满整个屏幕并且结束运行旧的Activity又在前台重新运行,就会调用旧的Activity的onRestart()方法,前提是旧的Activity没有被系统回收掉。
  7. onDestroy():当Activity被销毁之前调用。

以上就是Activity生命周期的详细描述。

  咱们的大诗人陆游说的好:” 纸上得来终觉浅 绝知此事要躬行”。接下来咱们就一起动手,去验证一下Activity的生命周期。

  首先先建立一个android project 取名为Activity_02.

创建一个Activity叫ActivityLifeCycle.在这个Activity中我们去实现这7个回调方法。并在这7个方法中打印一句话。

 1 package edu.activity.viking.test;
 2 
 3 import android.app.Activity;
 4 import android.os.Bundle;
 5 
 6 public class ActivityLifeCycle extends Activity 
 7 {
 8     /** Called when the activity is first created. */
 9     @Override
10     public void onCreate(Bundle savedInstanceState)
11     {
12         super.onCreate(savedInstanceState);
13         setContentView(R.layout.main);
14         System.out.println("run onCreate");
15     }
16 
17     
18     @Override
19     protected void onStart()
20     {
21         System.out.println("run onStart");
22         super.onStart();
23     }
24 
25 
26     @Override
27     protected void onRestart()
28     {
29         System.out.println("run onRestart");
30         super.onRestart();
31     }
32 
33     @Override
34     protected void onResume()
35     {
36         System.out.println("run onResume");
37         super.onResume();
38     }
39 
40 
41     @Override
42     protected void onPause()
43     {
44         System.out.println("run onPause");
45         super.onPause();
46     }
47 
48     @Override
49     protected void onStop()
50     {
51         System.out.println("run onStop");
52         super.onStop();
53     }
54     
55     @Override
56     protected void onDestroy()
57     {
58         System.out.println("run onDestroy");
59         super.onDestroy();
60     }
61 }

现在我们启动Activity看看控制台输出的信息。

我们可以看到在Activity启动的过程中,系统调用了

OnCreate()-àonStart()-àonResume()

三个方法。

我们现在按Back键退出,看看会运行什么。

我可以看到当我们退出Activity时系统调用了

OnPause()-àonStop()-àonDestroy()

三个方法。

 

接下来我们测试另外一种情况。我们需要在我们的Activity_02这个项目中再添加一个Activity,名叫:OtherActivity当然它也必须继承咱们的Activity

我们把新建立的OtherActivity也实现这7个方法并且打印一句话。

 1 package edu.activity.viking.test;
 2 
 3 import android.app.Activity;
 4 import android.os.Bundle;
 5 
 6 public class OtherActivity extends Activity
 7 {
 8     @Override
 9     protected void onCreate(Bundle savedInstanceState)
10     {
11         super.onCreate(savedInstanceState);
12         setContentView(R.layout.other_activity);
13         System.out.println("OtherActivity onCreate");
14     }
15     
16     @Override
17     protected void onStart()
18     {
19         System.out.println("OtherActivity onStart");
20         super.onStart();
21     }
22     
23     @Override
24     protected void onRestart()
25     {
26         System.out.println("OtherActivity onRestart");
27         super.onRestart();
28     }
29     
30     @Override
31     protected void onResume()
32     {
33         System.out.println("OtherActivity onResume");
34         super.onResume();
35     }
36     
37     @Override
38     protected void onPause()
39     {
40         System.out.println("OtherActivity onPause");
41         super.onPause();
42     }
43     
44     @Override
45     protected void onStop()
46     {
47         System.out.println("OtherActivity onStop");
48         super.onStop();
49     }
50     
51     @Override
52     protected void onDestroy()
53     {
54         System.out.println("OtherActivity onDestroy");
55         super.onDestroy();
56     }
57 }

在onCreate方法中,我们使用了setContentView方法,这个方法指明我们要显示other_activity.xml文件。Other_activity.xml文件内容很简单。只有一个TextView控件显示一句话。

代码:

 1 <?xml version="1.0" encoding="utf-8"?>
 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 3         android:layout_width="fill_parent"
 4         android:layout_height="fill_parent"
 5         android:orientation="vertical"
 6 >
 7     <TextView
 8         android:layout_width="fill_parent"
 9         android:layout_height="wrap_content"
10         android:text="other_activity"
11     />
12 </LinearLayout>

然后我们必须修改ActivityLifeCycle文件。以下是修改好的代码。

 1 package edu.activity.viking.test;
 2 
 3 import android.app.Activity;
 4 import android.content.Intent;
 5 import android.os.Bundle;
 6 import android.view.View;
 7 import android.widget.Button;
 8 
 9 public class ActivityLifeCycle extends Activity 
10 {
11     /** Called when the activity is first created. */
12     @Override
13     public void onCreate(Bundle savedInstanceState)
14     {
15         super.onCreate(savedInstanceState);
16         setContentView(R.layout.main);
17         System.out.println("run onCreate");
18         //通过findViewById这个方法从other_activity.xml中找到一个Button
19         Button button = (Button)findViewById(R.id.button);
20         //为按钮注册监听器
21         button.setOnClickListener(new View.OnClickListener()
22         {
23 
24             public void onClick(View v)
25             {
26                 Intent intent = new Intent();
27                 intent.setClass(ActivityLifeCycle.this, OtherActivity.class);
28                 ActivityLifeCycle.this.startActivity(intent);
29             }
30             
31         });
32     }
33 
34     
35     @Override
36     protected void onStart()
37     {
38         System.out.println("run onStart");
39         super.onStart();
40     }
41 
42 
43     @Override
44     protected void onRestart()
45     {
46         System.out.println("run onRestart");
47         super.onRestart();
48     }
49 
50     @Override
51     protected void onResume()
52     {
53         System.out.println("run onResume");
54         super.onResume();
55     }
56 
57 
58     @Override
59     protected void onPause()
60     {
61         System.out.println("run onPause");
62         super.onPause();
63     }
64 
65     @Override
66     protected void onStop()
67     {
68         System.out.println("run onStop");
69         super.onStop();
70     }
71     
72     @Override
73     protected void onDestroy()
74     {
75         System.out.println("run onDestroy");
76         super.onDestroy();
77     }
78 }

本次的修改集中在onCreate方法中。

最后必须把新建立的OtherActivity在androidManifest.xml中进行注册,否则系统会报错噢。

到目前为止,我们的修改就完成了,我们再运行一下,看看控制台给出的信息。

程序运行后,同样是先执行ActivityLifeCycle中的onCreate-onStart-onResume方法。

我们点击OtherActivity按钮。

从图中我们可以看到,点击OtherActivity按钮后,旧的Activity立即执行了onPause方法,接着新的Activity执行了onCreate-àonStart-àonResume方法。当新的Activity变为可见状态时,旧的Activity执行了onStop方法。

  这时我们再按back键,让新的Activity结束运行,让旧的Activity重新回到前台。

 

按back键后,新的Activity执行了onPause方法,接着旧的Activity执行了onRestart-àonStart-àonResume方法,这里值得注意的是,它并没有调用onCreate方法,而是执行了onRestart方法,这也证明了旧的Activity被新的Activity遮挡住以后,并没有被销毁掉,而是一直存在。所以当旧的Activity重新在前台运行时只调用onRestart方法而不会调用onCreate方法。

  当旧的Activity为可见状态时,新的Activity调用了onStop-àonDestroy方法。也就是说新的Activity被销毁掉了。

  如果这时候我们再按一次back键,旧的Activity也将会被销毁掉。

 

 

这时旧的activity就会执行onPause-àonStop-àonDestroy方法。

这种情况弄明白以后,我们就来说说,当新启动的Activity没有完全充满屏幕的情况,看看是否与上面解释的一样。那么我们怎么才能让新启动的Activity不充满屏幕呢?很简单,只需要在AndroidManifest.xml中的<activity>标签中添加一个属性即可。看图:

添加完这个属性后,我们再来看看运行的情况如何。

首次运行程序,还是调用onCreate-àonStart-àonResume方法。

点击OtherActivity按钮。

 

看,这次新的Activity并没有充满整个屏幕,所以旧的Activity只是调用了onPause方法,并没有调用onStop方法。

咱们按back键,回到上一个Activity.

当旧的Activity重新运行以后,果然只是调用了onResume方法。

再次点击back键。我们看到了这时候新的Activity才会调用onStop方法和onDestroy方法。为什么会这样呢?这一点小菜我也不是很明白,小菜猜想也许在第一次点击back键时,对话框式的activity只是被隐藏起来了,并没有被旧的Activity覆盖。所以并没有调用onStop和onDestroy方法。当然这都只是小菜个人的猜想,如果有大牛知道答案的,麻烦告诉小菜一声。省得小菜误人子弟了。

“这篇文章好长啊,我都快看不下去了”。没关系最后一个知识点了,大家再坚持一会。

   最后的一个是不同的退出方式,不同的进入方式对Activity生命周期的影响。

以上总结了2种不同方式退出,2种不同方式进入Activity的情况。按Home键退出时起始Activity并没有销毁掉,也就是说并没有调用onDestroy方法。所以再2种不同的方式进入时,它依然时从onRestart方法开始运行。

  而按back键退出时,Activity是被销毁掉了的,当以2种不同的方式再次运行时,Activity会从onCreate方法开始运行。

  由于写的太多了,已经有人开始扔丑鸡蛋了,我就不给大家做示范了,大家自己动手实验一下,看看是不是我所说的这样。

 好啦,好啦终于写完了,好长啊,没想到写了这么多。那么再见啦,下一篇博文咱们继续深入Activity.

转载于:https://www.cnblogs.com/zzy0127/archive/2012/09/05/2672104.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/463373.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C C++面试常问简答题(1)

1.new、delete、malloc、free关系 delete会调用对象的析构函数,和new对应free只会释放内存&#xff0c;new调用构造函数。malloc与free是C/C语言的标准库函数&#xff0c;new/delete是C的运算符。它们都可用于申请动态内存和释放内存。对于非内部数据类型的对象而言&#xff0c…

CSS hack:针对IE6,IE7,IE8,IE9,firefox显示不同效果

区别不同浏览器的CSS hack写法&#xff1a; 区别IE6与其它浏览器&#xff1a; background:orange;_background:blue; 区别IE6与IE7&#xff1a; background:green !important;background:blue; 区别IE6、IE7与FF&#xff1a; background:orange; *background:green…

CAP定理以及证明

历史 这个定理起源于柏克莱加州大学University of California, Berkeley的计算机科学家埃里克布鲁尔在2000年的分布式计算原则研讨会&#xff08;Symposium on Principles of Distributed Computing&#xff08;PODC&#xff09;&#xff09;上提出的一个猜想。 在2002年&…

java线程自带队列的使用以及线程阻塞

java线程&#xff0c;设置队列的大小实现队列阻塞 public class QueueThreads {private static int nThreads 4;//Runtime.getRuntime().availableProcessors() * 2 1;private static BlockingQueue<Runnable> queue new ArrayBlockingQueue<Runnable>(4);//队列…

init/inittab

一、什么是init  init是Linux系统操作中不可缺少的程序之一。 是一个由内核启动的用户级进程。  内核启动&#xff08;已经被载入内存&#xff0c;开始运行&#xff0c;并已初始化所有的设备驱动程序和数据结构等&#xff09;之后&#xff0c;就通过启动一个用户级程序init…

ASP.NET下QueryString不同字符编码间强制转换的解决方案

正常的情况下&#xff0c;现在asp.net的网站很多都直接使用UTF8来进行页面编码的&#xff0c;这与Javascript、缺省网站的编码是相同的&#xff0c;但是也有相当一部分采用GB2312。对于GB2312的网站如果直接用javascript进行ajax数据提交&#xff0c;例如&#xff1a;http://ww…

C C++面试常问简答题(2)

51.h头文件中的ifndef/define/endif 的作用&#xff1f; 答&#xff1a;防止该头文件被重复引用。 52.&#xff03;i nclude<file.h> 与 &#xff03;i nclude "file.h"的区别&#xff1f; 答&#xff1a;前者是从Standard Library的路径寻找和引用file.h&…

GDB 调试指南

大家好&#xff0c; 好久没给大家带来原创干货了&#xff0c;导致很多新来的小伙伴以为我这个号就是个机构号&#xff0c;其实不是&#xff0c;这个是个人号&#xff0c;背后的小编我是一个有血有肉有情怀的人&#xff0c;不管怎么样&#xff0c;我的目的是尽量带给大家优质的干…

ASP.NET MVC3 异步刷新

ASP.NET MVC3 异步刷新2011-08-13 09:51:53标签&#xff1a;MVC3 异步刷新 休闲 N Layer 职场原创作品&#xff0c;允许转载&#xff0c;转载时请务必以超链接形式标明文章 原始出处 、作者信息和本声明。否则将追究法律责任。http://leelei.blog.51cto.com/856755/638408好久没…

一个反射的妙用案例

今天在工作中遇到一种场景: 一个表格有10个列,要求当点击某列列头时,下拉展示该列的所有数据 解决的常规办法是根据传入的列参数值,判断是哪一列,使用switch()或者if-else判断过滤出哪一列的值 但这个办法太臃肿,如果有100个字段,那这个分支选择就太大了 所以采用反射,你传什么…

常规键盘快捷键

按键 目的 Ctrl A 全选Ctrl B 整理收藏夹Ctrl C 复制Ctrl D 删除/添加收藏Ctrl E 搜索助理Ctrl F 查找Ctrl H 历史记录Ctrl I 收藏夹Ctrl J IE7.0里的源Ctrl L &#xff1d;CtrlO 打开Ctrl M 网页搜索框中的确定&#xff08;等于回车&#xff09;Ctrl N 新窗…

指针和引用的区别和联系

在c的学习中&#xff0c;我们经常被应该如何使用指针和引用这个问题所困扰&#xff0c;那么我这里给大家说一下在我的学习过程中对指针和引用的理解&#xff0c;和它们之间的区别&#xff0c;希望各位朋友给出不同的意见并且指出我在学习中的一些错误首先我们来聊一下指针&…

编译rocksdb源码导致的部署失败

这几天经历了一次心酸的历程&#xff0c;使用了rocksdb第三方库&#xff0c;编译器是7.2&#xff0c;rocksdb是20190701从github上取下来的&#xff0c;由于rocksdb自己的CMakeList.txt中使用了-marchnative编译参数&#xff0c;强制使用了编译代码服务器的cpu指令集&#xff0…

跌倒的收获

有个"渔王"非常苦恼&#xff0c;就因为三个儿子的捕鱼技术都很一般。他常向人诉苦&#xff1a;"我从儿子们刚懂事起就传授技术&#xff0c;怎么他们都比不上平常人的孩子&#xff1f;" 一位路人听后&#xff0c;问&#xff1a;"你一直是手把手地教他们…

检测APK是否混淆

目录 为什么要检测APK是否混淆混淆的优点混淆的缺点APK的混淆的分类检测工具检测人工检测自动化检测为什么要检测APK是否混淆 apk代码混淆就是为了保护代码安全&#xff0c;防止被反编译拿到源码做审计找出危险漏洞&#xff0c;现在大部分的APK都会做混淆。 下面分析混淆APK后的…

基于asp.net的Web开发架构探索(转)

问题由来 最近在研究适合团队开发的web架构解决方案&#xff0c;该架构即要适合分工协作又要有一定扩展性&#xff0c;适合不同的数据库需要&#xff0c;因此我查阅了一些资料&#xff0c;初步构想出了一套架构&#xff0c;请各位多多指教。 探索 web开发架构最经典莫过于三层架…

ubuntu要更新18.04了,lei了lei了~~~

Ubuntu 18.04 LTS将于2018年4月26日发布。开发商现在有六个月的时间来打造“Bionic Beaver 仿生海狸”。 对于那些你不知道Ubuntu 4 &#xff08;xx.04&#xff09;版本遵循27周的时间表&#xff08;而不是10月发行的25周时间表&#xff0c;由于圣诞节和新年的小事情&#xff0…

SkipList 以及高度的确定

转载&#xff1a;https://www.cnblogs.com/lnlvinso/p/8848883.html 结果&#xff1a;skiplist的高度是个随机值。 SkipList理解 记下自己对跳表SkipList的理解。 SkipList采用空间换时间的思想&#xff0c;通过增加数据间的链接&#xff0c;达到加快查找速度的目的。 数据库L…

20个正则表达式,举一反三,相信对你很有用

转载:https://www.cnblogs.com/wxd0108/p/5580772.html 正则表达式经常被用于字段或任意字符串的校验&#xff0c;如下面这段校验基本日期格式的JavaScript代码&#xff1a; var reg /^(\\d{1,4})(-|\\/)(\\d{1,2})\\2(\\d{1,2})$/; var r fieldValue.match(reg); if(rnull)a…

约瑟夫环问题---循环单链表

约瑟夫环问题是比较经典的问题&#xff0c;原来做的题目是依次输出数字&#xff0c;而原来的循环链表结构不改变&#xff0c;今天遇到一道题是要求按照顺序重新组成一个循环单链表。 题目&#xff1a;一些人围坐一圈报数&#xff0c;形成一个循环单链表&#xff0c;当报数是m或…