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,一经查实,立即删除!

相关文章

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);//队列…

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

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

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好久没…

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

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

检测APK是否混淆

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

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

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

SkipList 以及高度的确定

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

IIS AppCreate子目录的错误(0x80020006)

这几天做了升级用的安装包,需要在原来的ASP 的虚拟目录下&#xff0c;再创建一个新的ASPNet 虚拟目录。上网查了C# iis设定的资料&#xff0c;按照上面一路做下来&#xff0c;还是无法成功过。 代码只有两行&#xff0c;如下&#xff1a;DirectoryEntry siteVDir new Director…

网络通信TCP协议三次握手

刚刚看linux公社看见里面一个讲TCP的文章&#xff0c;文章讲的很有意思生动形象&#xff0c;很有助于对TCP协议的理解和掌握&#xff0c;所以转载过来方便以后看一下HAHA~~~TCP是什么? TCP(Transmission Control Protocol 传输控制协议)是一种面向连接(连接导向)的、可靠的、 …

Android入门逆引手册 - 12 评分条(RatingBar)的使用

这里介绍评分条android.widget.RatingBar类的使用。 ● 评分&#xff08;星&#xff09;的最大数的设置&#xff0c;调用setNumStars()方法。● 现在的评分的设置&#xff0c;调用setRating()方法。 例程源码(Java)[java]RatingBar ratingBar (RatingBar)findViewById(id.rati…

数据库事务的四大特性以及事务的隔离级别

本篇讲诉数据库中事务的四大特性&#xff08;ACID&#xff09;&#xff0c;并且将会详细地说明事务的隔离级别。 如果一个数据库声称支持事务的操作&#xff0c;那么该数据库必须要具备以下四个特性&#xff1a; ⑴ 原子性&#xff08;Atomicity&#xff09; 原子性是指事务包含…

Paypal 在线支付接口应用从零开始,第2节,[支付API原理及流程]

今天看看Paypal支付流程和简单的认证原理,我画了一张图.应该能表达这两点意思了我们的站点名字,为了好理解,暂且就定为西狐的网站吧.点此查看清晰原图恩,理论知识很重要哈,先把这图理解了,下一步我们编程使用沙盒测试就很简单了.如果想更多研究一下还可直接查看Paypal官方提供的…

PLSQL DEVELOPER 使用技巧

为什么80%的码农都做不了架构师&#xff1f;>>> 1、右键菜单 在PL/SQL Developer&#xff08;下面简称PLD&#xff09;中的每一个文本编辑窗口&#xff0c;如SQL Window&#xff0c;Command Window和Porgram Window&#xff0c;右键点击某个对象名称&#xff0c;会…

Android Drawable绘图学习笔记

如何获取 res 中的资源 数据包package&#xff1a;android.content.res 主要类&#xff1a;ResourcesAndroid SDK中的简介&#xff1a;Class for accessing an application’s resources.Class for accessing an application’s resources. This sits on top of the asset mana…

C#.NET中的事件2

/** Created by SharpDevelop. * User: noo * Date: 2009-8-17 * Time: 15:34 * * 事件2 */usingSystem ;usingSystem .Windows .Forms ;classTest { staticvoidMain()//入口函数{ Form frmnewForm ();//新建一窗体frm.Text "我的窗体"; …

HTML学习之基础

HTML是网页的标记语言不是编程语言&#xff0c;有一些标记段组成。大小写不敏感&#xff0c;可以用常用的编辑器软件编写用浏览器打开即可 有不同的版本<!DOCTYPE html> <meta charset"utf-8">在<title>前为了能正常显示中文。 超链接&#xff1a;…

Varint

什么是Varint Varint 是一种紧凑的表示数字的方法。它用一个或多个字节来表示一个数字&#xff0c;值越小的数字使用越少的字节数。这能减少用来表示数字的字节数。 比如对于 int32 类型的数字&#xff0c;一般需要 4 个 byte 来表示。但是采用 Varint&#xff0c;对于很小的 …

Ubuntu 17.10安装Qt 5.10环境与Qt Creator 4.5开发工具(转自linux公社)

记录下在Ubuntu 17.10搭建Qt环境与安装Qt Creator开发工具的过程。机器装的Linux是Ubuntu 17.10&#xff0c;16.04与17.04的应该也相同。Qt 5.10和Qt 3D Studio发布 http://www.linuxidc.com/Linux/2017-12/149267.htm 1&#xff0c;Qt安装 1.1 下载Qt 这里提供Qt Creator的下…

C#基础(201)--常量枚举

本文知识点&#xff1a; 1.掌握常量的定义和使用方法 2.理解枚举的作用和特点 3.掌握枚举的使用方法 1.1.常量的定义语法 const 数据类型 常量名称 值&#xff1b; 1.2.常见错误 1.3常量的使用时机 经常使用并且值不变的变量&#xff0c;可以定义为常量 2.1枚举的作用及其…