前面两期我们学习了Activity的创建和注册、以及启动和关闭,也学会了重写onCraete方法,这些知识在实际开发中远远不够,还需要学习了解更多。

生命周期就是一个对象从创建到销毁的过程,每一个对象都有自己的生命周期。同样, Activity也具有相应的生命周期。

一、Activity状态

一个Android应用程序往往包含多个Activity,当Activity处于Android应用中运行时,每个Activity的状态都不一样。Activity的活动状态由Android以Activity栈的形式管理,当前活动的Activity位于栈顶。随着不同应用的运行,每个Activity都有可能从活动状态转入非活动状态,也可能从非活动状态转入活动状态。

Activity的生命周期中一共有4种状态,分别如下:

1、运行状态(Active or Running)

当Activity在屏幕的最前端时,它处于Activity栈顶,是可见的、有焦点的,可以用来处理用户的常见操作,如点击、双击、长按事件等,这种状态称为运行状态,也叫活动状态。

2、暂停状态(Paused)

在某些情况下,Activity对用户来说仍然是可见的,但它不再拥有焦点,即用户对它的操作是没有实际意义的。例如,当最上面的Activity没有完全覆盖屏幕或者是透明的,被覆盖的Activity仍然对用户可见,并且存活(它保留着所有的状态和成员信息并保持与Activity管理器的连接)。但当内存不足时,这个暂停状态的Activity可能会被杀死。

3、停止状态(Stopped)

当Activity完全不可见时,它就处于停止状态,但仍然保留着当前状态和成员信息。然而这些对用户来说都是不可见的,如果当系统内存不足时,这个Activity很容易被杀死。

4、销毁状态(Killed)

当Activity运行结束,或Activity所在的进程结束时,这种状态称为销毁状态,也叫非活动状态。这时Activity已从Activity栈中移除,需要重新启动才可以显示和使用。当系统内存需要被用在其他地方的时候,一个停止状态的Activity被杀掉。

另外当Activity处于运行状态时,Android会尽可能地保持它的运行,即使出现内存不足的情况,Android也会先杀死栈底部的Activity,来确保可见的Activity正常运行。

关于Activity的这四种状态,是可以相互转化的,如下图所示。

值得注意的时这四种状态中,运行状态和暂停状态是可见的,停止状态和销毁状态是不可见的。

二、 Activity生命周期

Activity从一种状态转变到另一种状态时会触发一些事件,执行一些回调方法来通知状态的变化,这就是Activity的生命周期。

Activity的生命周期及其相关方法的回调,如下图所示。

从上图可以看到在Activity的生命周期中,有如下几个方法被系统回调。

  • onCreate(Bundle savedStatus):创建Activity时被回调。该方法只会被调用一次。

  • onStart():启动 Activity 时被回调。

  • onRestart():重新启动 Activity 时被回调。

  • onResume():恢复 Activity 时被回调。在onStart()方法后一定会回调 onResume()方法。

  • onPause():暂停 Activity 时被回调。

  • onStop():停止 Activity 时被回调。

  • onDestroy():销毁 Activity 时被回调。该方法只会被调用一次。

为了更好的掌握Activity生命周期及其方法,接下来通过一个实例来学习,主要实现两个Activity之间跳转时生命周期方法变化的过程。

仍然使用上期创建的ActivitySample工程,为了便于代码管理,这里新建一个activitylifecycle的Module。该Module一共包含了2个Activity,并在AndroidManifest清单文件中配置两个Activity。

其中第一个Activity的界面布局非常简单,只包含2个按钮,其中第一个按钮的作用主要是启动第二个Activity,第二个按钮的作用是退出当前Activity。第一个Activity对应的布局文件activity_main.xml的代码如下:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<Button
android:id="@+id/start_normal_activity_btn"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="启动Activity"/>
<Button
android:id="@+id/quit_activity_btn"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="退出Activity"/>
</LinearLayout>

第二个Activity对应的布局文件activity_second.xml的代码如下:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"> <TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="这是第二个Activity"/>
</LinearLayout>

第一个MainActivity类主要用于重写Activity的生命周期方法,并在每个方法中打印出Log以便观察,具体代码如下所示:

package com.jinyu.cqkxzsxy.android.activitylifecycle;

import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button; public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private static final String TAG = "MainActivity";
private Button mStartActivityBtn = null;
private Button mQutiActivityBtn = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.d(TAG, "onCreate()"); mStartActivityBtn = (Button) findViewById(R.id.start_normal_activity_btn);
mQutiActivityBtn = (Button) findViewById(R.id.quit_activity_btn);
mStartActivityBtn.setOnClickListener(this);
mQutiActivityBtn.setOnClickListener(this);
} @Override
protected void onStart() {
super.onStart();
Log.d(TAG, "onStart()");
} @Override
protected void onRestart() {
super.onRestart();
Log.d(TAG, "onRestart()");
} @Override
protected void onResume() {
super.onResume();
Log.d(TAG, "onResume()");
} @Override
protected void onPause() {
super.onPause();
Log.d(TAG, "onPause()");
} @Override
protected void onStop() {
super.onStop();
Log.d(TAG, "onStop()");
} @Override
protected void onDestroy() {
super.onDestroy();
Log.d(TAG, "onDestroy()");
} @Override
public void onClick(View view) {
switch (view.getId()){
case R.id.start_normal_activity_btn:
// 启动普通的Activity
Intent intent = new Intent(MainActivity.this, SecondActivity.class);
startActivity(intent);
break;
case R.id.quit_activity_btn:
// 结束该Activity
MainActivity.this.finish();
break;
default:
break;
}
}
}

为了观察MainActivity停止状态时的生命周期,需要在当前项目中创建第二个SecondActivity,由于不需要对第二个Activity进行界面操作,因此添加activity_second.xml文件即可不需要其他操作。在第二个Activity中同样实现Activity生命周期中的方法,在每个方法中打印Log信息。

package com.jinyu.cqkxzsxy.android.activitylifecycle;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log; public class SecondActivity extends AppCompatActivity {
private static final String TAG = "SecondActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second);
Log.d(TAG, "onCreate()");
} @Override
protected void onStart() {
super.onStart();
Log.d(TAG, "onStart()");
} @Override
protected void onRestart() {
super.onRestart();
Log.d(TAG, "onRestart()");
} @Override
protected void onResume() {
super.onResume();
Log.d(TAG, "onResume()");
} @Override
protected void onPause() {
super.onPause();
Log.d(TAG, "onPause()");
} @Override
protected void onStop() {
super.onStop();
Log.d(TAG, "onStop()");
} @Override
protected void onDestroy() {
super.onDestroy();
Log.d(TAG, "onDestroy()");
}
}

在AndroidManifest.xml文件中注册已经创建好的Activity,即在清单文件中添加一个<activity>结点,指定Activity径名。

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.jinyu.cqkxzsxy.android.activitylifecycle"> <application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity> <activity android:name=".SecondActivity" />
</application>
</manifest>

上述操作完成后运行程序,首先会显示第一个Activity界面,如下图所示。

这时在Android Studio的LogCat窗口会打印MainActivity生命周期中的执行方法,如下图所示:

从上图可以看到,应用程序启动 MainActivity依次调用了 onCreate()、onStart()、onResume(),这个顺序是第一个Activity从创建到显示在前台到用户可点击的过程。

接下来单击第一个按钮启动第二个Activity。当第一个界面跳转到第二个界面时,LogCat 窗口会打印MainActivity和SecondActivity生命周期中的执行方法,如下图所示:

从上图可以看到,当跳转到第二个界面时,MainActivity首先失去焦点执行了onPause()方法,然后SecondActivity依次执行了onCreate()、onStart()、onResume()方法从创建到前台可见, 这时 MainActivity执行了onStop()方法。

现在再观察一下从第二个Activity按返回键回到第一个Activity生命周期的LogCat 信息,如下图所示:

从上图可以看到,单击返回键之后,SecondActivity同样先执行了onPause()方法,然后 MainActivity执行了 onRestart()、onStart()、onResume()方法,随后SecondActivity才彻底关闭,执行 了 onStop()、onDestory()。在 MainActivity打开 SecondActivity时,MainActivity并没有执 onDestory()方法而是执行了 onStop()方法。因此,从 SecondActivity返回到 MainActivity时,MainActivity执行了 onRestart() 方法。

单击退出Activity按钮,MainActivity将会结束自己,并且可以在LogCat 窗口看到如下图所示的输出:

从该示例可以看到,各生命周期方法的调用完全符合前面所讲。

将Activity的生命周期方法和Activity的四种状态结合起来,用另一种方式表现出来,可以得到下面的示意图。

关于Activity的生命周期方法就先学到这里,下期再继续学习其他有关Activity的内容。

今天就先到这里,如果有问题欢迎留言一起探讨,也欢迎加入Android零基础入门技术讨论微信群,共同成长!

如果该系列分享对你有帮助,就动动手指关注、点赞、留言吧,你的互动就是对我最大的鼓励!

此文章版权为微信公众号分享达人秀(ShareExpert)——鑫鱻所有,若需转载请联系作者授权,特此声明!

往期总结回顾:

Android零基础入门第1节:Android的前世今生

Android零基础入门第2节:Android 系统架构和应用组件那些事

Android零基础入门第3节:带你一起来聊一聊Android开发环境

Android零基础入门第4节:正确安装和配置JDK, 高富帅养成第一招

Android零基础入门第5节:善用ADT Bundle, 轻松邂逅女神

Android零基础入门第6节:配置优化SDK Manager, 正式约会女神

Android零基础入门第7节:搞定Android模拟器,开启甜蜜之旅

Android零基础入门第8节:HelloWorld,我的第一趟旅程出发点

Android零基础入门第9节:Android应用实战,不懂代码也可以开发

Android零基础入门第10节:开发IDE大升级,终于迎来了Android Studio

Android零基础入门第11节:简单几步带你飞,运行Android Studio工程

Android零基础入门第12节:熟悉Android Studio界面,开始装逼卖萌

Android零基础入门第13节:Android Studio个性化配置,打造开发利器

Android零基础入门第14节:使用高速Genymotion,跨入火箭时代

Android零基础入门第15节:掌握Android Studio项目结构,扬帆起航

Android零基础入门第16节:Android用户界面开发概述

Android零基础入门第17节:文本框TextView

Android零基础入门第18节:输入框EditText

Android零基础入门第19节:按钮Button

Android零基础入门第20节:复选框CheckBox和单选按钮RadioButton

Android零基础入门第21节:开关组件ToggleButton和Switch

Android零基础入门第22节:图像视图ImageView

Android零基础入门第23节:图像按钮ImageButton和缩放按钮ZoomButton

Android零基础入门第24节:自定义View简单使用,打造属于你的控件

Android零基础入门第25节:简单且最常用的LinearLayout线性布局

Android零基础入门第26节:两种对齐方式,layout_gravity和gravity大不同

Android零基础入门第27节:正确使用padding和margin

Android零基础入门第28节:轻松掌握RelativeLayout相对布局

Android零基础入门第29节:善用TableLayout表格布局

Android零基础入门第30节:两分钟掌握FrameLayout帧布局

Android零基础入门第31节:少用的AbsoluteLayout绝对布局

Android零基础入门第32节:新推出的GridLayout网格布局

Android零基础入门第33节:Android事件处理概述

Android零基础入门第34节:Android中基于监听的事件处理

Android零基础入门第35节:Android中基于回调的事件处理

Android零基础入门第36节:Android系统事件的处理

Android零基础入门第37节:初识ListView

Android零基础入门第38节:初识Adapter

Android零基础入门第39节:ListActivity和自定义列表项

Android零基础入门第40节:自定义ArrayAdapter

Android零基础入门第41节:使用SimpleAdapter

Android零基础入门第42节:自定义BaseAdapter

Android零基础入门第43节:ListView优化和列表首尾使用

Android零基础入门第44节:ListView数据动态更新

Android零基础入门第45节:网格视图GridView

Android零基础入门第46节:列表选项框Spinner

Android零基础入门第47节:自动完成文本框AutoCompleteTextView

Android零基础入门第48节:可折叠列表ExpandableListView

Android零基础入门第49节:AdapterViewFlipper图片轮播

Android零基础入门第50节:StackView卡片堆叠

Android零基础入门第51节:进度条ProgressBar

Android零基础入门第52节:自定义ProgressBar炫酷进度条

Android零基础入门第53节:拖动条SeekBar和星级评分条RatingBar

Android零基础入门第54节:视图切换组件ViewSwitcher

Android零基础入门第55节:ImageSwitcher和TextSwitcher

Android零基础入门第56节:翻转视图ViewFlipper

Android零基础入门第57节:DatePicker和TimePicker选择器

Android零基础入门第58节:数值选择器NumberPicker

Android零基础入门第59节:常用三大Clock时钟组件

Android零基础入门第60节:日历视图CalendarView和定时器Chronometer

Android零基础入门第61节:滚动视图ScrollView

Android零基础入门第62节:搜索框组件SearchView

Android零基础入门第63节:值得借鉴学习的选项卡TabHost

Android零基础入门第64节:揭开RecyclerView庐山真面目

Android零基础入门第65节:RecyclerView分割线开发技巧

Android零基础入门第66节:RecyclerView点击事件处理

Android零基础入门第67节:RecyclerView数据动态更新

Android零基础入门第68节:RecyclerView添加首尾视图

Android零基础入门第69节:ViewPager快速实现引导页

Android零基础入门第70节:ViewPager打造TabHost效果

Android零基础入门第71节:CardView简单实现卡片式布局

Android零基础入门第72节:SwipeRefreshLayout下拉刷新

Android零基础入门第73节:Activity创建和配置

Android零基础入门第74节:Activity启动和关闭

Android零基础入门第75节:Activity状态和生命周期方法的更多相关文章

  1. Android零基础入门第86节:探究Fragment生命周期

    一个Activity可以同时组合多个Fragment,一个Fragment也可被多个Activity 复用.Fragment可以响应自己的输入事件,并拥有自己的生命周期,但它们的生命周期直接被其所属的 ...

  2. Android零基础入门第22节:ImageView的属性和方法大全

    原文:Android零基础入门第22节:ImageView的属性和方法大全 通过前面几期的学习,TextView控件及其子控件基本学习完成,可以在Android屏幕上显示一些文字或者按钮,那么从本期开 ...

  3. Android零基础入门第89节:Fragment回退栈及弹出方法

    在上一期分享的文章末尾留了一个课后作业,有去思考如何解决吗?如果已经会了那么恭喜你,如果还不会也没关系,本期一起来学习. 一.回退栈 在前面两期的示例中,当我们完成一些操作后,如果想要回到操作之前的状 ...

  4. Android零基础入门第88节:Fragment显示和隐藏、绑定和解绑

    在上一期我们学习了FragmentManager和FragmentTransaction的作用,并用案例学习了Fragment的添加.移除和替换,本期一起来学习Fragment显示和隐藏.绑定和解绑. ...

  5. Android零基础入门第87节:Fragment添加、删除、替换

    前面一起学习了Fragment的创建和加载,以及其生命周期方法,那么接下来进一步来学习Fragment的具体使用,本期先来学习Fragment添加.删除.替换. 一.概述 在前面的学习中,特别是动态加 ...

  6. Android零基础入门第83节:Activity间数据传递方法汇总

    在Activity间传递的数据一般比较简单,但是有时候实际开发中也会传一些比较复杂的数据,本节一起来学习更多Activity间数据的传递. 一.常用数据类型 在前面几节我们只学习了一些常用类型的数据传 ...

  7. Android零基础入门第82节:Activity数据回传

    上一节学习了将简单的数据从MainActivity传递到SecondActivity,本节一起来学习数据如何从SecondActivity回传到MainActivity. 一.简介 前面己经提到,Ac ...

  8. Android零基础入门第81节:Activity数据传递

    在Android开发中,经常要在Activity之间传递数据.前面也学习了Activity和Intent相关基础,接下来一起来学习Activity的数据传递. 一.简介 通过前面的学习知道,Inten ...

  9. Android零基础入门第77节:Activity任务栈和启动模式

    通过前面的学习,Activity的基本使用都已掌握,接下来一起来学习更高级的一些内容. Android采用任务栈(Task)的方式来管理Activity的实例.当启动一个应用时,Android就会为之 ...

随机推荐

  1. 【bzoj3555】[Ctsc2014]企鹅QQ 简单哈希

    传送门 题目分析 题意即求有多少对字符串只相差一个字符,枚举删除每个字符后的哈希, 看有多少相等即可. 比如有如下字符串:$Sd123$,其中S部分的哈希值为H,删除的是d,则原字符串的哈希值为$$( ...

  2. 【16.23%】【codeforces 586C】Gennady the Dentist

    time limit per test1 second memory limit per test256 megabytes inputstandard input outputstandard ou ...

  3. PostThreadMessage发送进程间消息(对话框向控制台发消息,控制台也可有消息循环)

    函数原型 BOOL PostThreadMessage( DWORD idThread, UINT Msg, WPARAM wParam, LPARAM lParam ); 1 2 3 4 5 6 T ...

  4. flex新的心得

    主要是对于flex: 与width: 的心得,先看代码. <head> <meta charset="UTF-8"> <meta name=" ...

  5. H∞一般控制问题的鲁棒叙述性说明

    Robust Control System:反馈控制有承受一定类不确定能力的影响,这一直保持在这种不确定的条件(制)稳定.动态特性(灵敏度)和稳态特性(逐步调整)的能力. 非结构不确定性(Unstru ...

  6. 从Client应用场景介绍IdentityServer4(三)

    原文:从Client应用场景介绍IdentityServer4(三) 在学习其他应用场景前,需要了解几个客户端的授权模式.首先了解下本节使用的几个名词 Resource Owner:资源拥有者,文中称 ...

  7. POJ 1988 Cube Stacking (种类并查集)

    题目地址:POJ 1988 这道题的查找合并的方法都能想的到,就是一点没想到,我一直天真的以为查询的时候,输入后能立即输出,这种话在合并的时候就要所有的结点值都要算出来,可是经过路径压缩之后,没办法所 ...

  8. mongoDB 入门手册

    MongoDB - 简介 官网:https://www.mongodb.com/ MongoDB 是一个基于分布式文件存储的数据库,由 C++ 语言编写,旨在为 WEB 应用提供可扩展的高性能数据存储 ...

  9. TCP 报文段结构

      源端口.目标端口:计算机上的进程要和其他进程通信是要通过计算机端口的,而一个计算机端口某个时刻只能被一个进程占用,所以通过指定源端口和目标端口,就可以知道是哪两个进程需要通信.源端口.目标端口是用 ...

  10. Leetcode 169 Majority Element 分治

    在一个长度为n的数组中找出出现次数超过(n+1)/2次的数 说明请参考编程之美中的2.3 class Solution { public: int majorityElement(vector< ...