•返回栈

  Android 中的活动是可以叠层的;

  我们每启动一个新的活动,就会覆盖在原活动之上;

  然后点击 Back 键会销毁最上面的活动,下面一个活动就会重新显示出来;

  其实 Android 是使用任务(Task)来管理活动的;

  一个任务就是一组存放在栈里的活动的集合,这个栈也被称作返回栈(Back Stack);

  栈是一种后进先出的数据结构,在默认情况下,每当我们启动了一个新的活动,它会在返回栈中入栈;

  并处于栈顶的位置,而每当我们按下 Back 键或者调用 finish() 方法去销毁一个活动时;

  处于栈顶的活动会出栈,这时,前一个入栈的活动就会重新处于栈顶位置;

  系统总是会显示栈顶的活动给用户。

•活动的状态

  • 运行状态
    • 当一个活动位于返回栈的栈顶时,这时活动就处于运行状态
    • 系统最不愿意回收的就是处于运行状态的活动,因为这会带来非常差的用户体验
  • 暂停状态

    • 当一个活动不再处于栈顶位置,但仍然可见时,这时活动就进入了暂停状态
    • 比如对话框形式的活动只会占用屏幕中间的部分区域,你还可以看到后边的界面
    • 这时,后面的活动就处于暂停状态
  • 停止状态

    • 当一个活动不在处于栈顶位置,并且完全处于不可见的时候,就进入了停止状态
    • 系统仍然会为这种活动保存相应的状态和成员变量,但是这并不是完全可靠的
    • 当其他地方需要内存时,处于停止状态的活动有可能会被系统回收
  • 销毁状态

    • 当一个活动从返回栈中移除后就变成了销毁状态
    • 系统倾向于回收处于这种状态的活动,从而保证手机内存充足

•活动的生存期

  Activity 类中定义了七个回调方法,覆盖了活动生命周期的每一个环节;

  • onCreate()

    • 每个活动中都重写这个方法,他会在活动第一次被创建的时候调用
    • 你应该在这个方法中完成活动的初始化操作,比如加载布局、绑定事件等
  • onStart()

    • 这个方法在活动由不可见变为可见的时候调用
  • onResume()

    • 这个方法在活动准备好和用户进行交互时调用
    • 此时的活动一定位于返回栈的栈顶,并且处于运行状态
  • onPause()

    • 这个方法在系统准备去启动或者恢复另一个活动的时候调用
    • 我们通常会在这个方法中将一些消耗 CPU 的资源释放掉以及保存一些关键数据
  • onStop()

    • 这个方法在活动完全不可见的时候调用
    • 它和  onPause()  方法的区别在于,如果启动的新活动是一个对话框样式的活动
    • 那么  onPause()  方法会执行, onStop()  方法不会执行
  • onDestroy()

    • 这个方法在活动被销毁之前调用
    • 之后活动的状态将变为销毁状态
  • onRestart()

    • 这个方法在活动由停止状态变为运行状态之前调用
    • 也就是活动被重新启动了
  以上七个方法除了  onRestart()  方法,其他都是两两相对的,从而又可以将活动分为三种生存期;
  • 完整生存期

    • 活动在  onCreate()  方法和  onDestroy()  方法之间所经历的就是完整生存期
    • 一般情况下,一个活动会在  onCreate()  方法中完成各种初始化操作
    • 而在  onDestroy()  方法中完成释放内存的操作
  • 可见生存期

    • 活动在  onStart()  方法和  onStop()  之间所经历的就是可见生存期
    • 在可见生存期内,活动对于用户总是可见的,即便有可能无法和用户进行交互
  • 前台生存期

    • 活动在  onResume()  方法和  onPause()  方法之间所经历的就是前台生存期
    • 这个生存期内,活动总是处于运行状态
    • 此时的活动是可以和用户进行相互的,我们平时看到和接触最多的也是这个状态下的活动

活动生命周期示意图

•体验活动的生命周期

准备工作

  新建一个项目,命名为 ActivityLifeCycleTest,并选择 Empty Activity;

  进入项目,将模式结构改成 Project 结构;

  接下来,我们需要额外新建两个 Empty Activity;

  点击 app/src/main/java,在包下右击->New->Activity->Empty Activity;

  新建的两个 Activity 分别命名为 NormalActivity和 DialogActivity;

  接下来就是敲代码的环节了;

activity_normal.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"> <TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="this is a normal activity"
android:textSize="20sp"
android:layout_centerInParent="true"/>
</RelativeLayout>

activity_dialog.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"> <TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="this is a dialog activity"
android:textSize="20sp"
android:layout_centerInParent="true"/> </RelativeLayout>

  通过代码可以看出,这两个布局文件的代码几乎没有区别,只是显示的文字不同;

  其实从名字上可以看出,这两个 Activity 一个表示普通活动,一个表示对话框活动;

  但我们并没有对  .java  文件任何修改,在哪里体现出 DialogActivity 为对话框活动呢?

  别着急,下面我们马上开始配置;

  打开 AndroidManifest.xml 文件;

  有没有发现什么不一样的?

  没错,在  .DialogActivity 的配置中;

  通过使用  android:theme="@style/Theme.AppCompat.Dialog" 将 DialogActivity 设置成对话框形式的主题;

  接下来,我们修改 activity_main.xml 中的布局;

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:padding="10dp"
android:orientation="vertical"> <Button
android:id="@+id/btn_1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Start Normal Activity"
android:textAllCaps="false"/> <Button
android:id="@+id/btn_2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Start Dialog Activity"
android:textAllCaps="false"/> </LinearLayout>

  可以看到,在该布局中加入了两个按钮;

  btn_1 用于启动 NormalActivity,btn_2 用于启动 DialogActivity;

  最后修改 MainActivity.java 中的代码;

MainActivity.java

public class MainActivity extends AppCompatActivity {

    public static final String TAG = "MainActivity";
private Button btn1;
private Button btn2; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.d(TAG, "onCreate: "); btn1 = findViewById(R.id.btn_1);
btn1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(MainActivity.this,NormalActivity.class);
startActivity(intent);
}
});
btn2 = findViewById(R.id.btn_2);
btn2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(MainActivity.this,DialogActivity.class);
startActivity(intent);
}
});
} @Override
protected void onStart() {
super.onStart();
Log.d(TAG, "onStart: ");
} @Override
protected void onResume() {
super.onResume();
Log.d(TAG, "onResume: ");
} @Override
protected void onPause() {
super.onPause();
Log.d(TAG, "onPause: ");
} @Override
protected void onRestart() {
super.onRestart();
Log.d(TAG, "onRestart: ");
} @Override
protected void onDestroy() {
super.onDestroy();
Log.d(TAG, "onDestroy: ");
} @Override
protected void onStop() {
super.onStop();
Log.d(TAG, "onStop: ");
}
}

  在  onCreate() 方法中,分别为两个按钮注册了点击事件,用于启动 NormalActivity 和 DialogActivity;

  然后在 Activity 的 7 个回调方法中分别打印一句话,这样我们就可以通过观察日志的方式来更直观的理解活动的生命周期;

  有关 Log 的用法,请参考我的这篇博客;

运行程序

  

  这时,观察 logcat 中的打印语句;

  可以看到,当  MainActivity 第一次被创建的时候,会依次执行 onCreate() , onStart()  和  onResume() 方法;

  然后,点击第一个按钮,启动 NomalActivity;

启动 NomalActivity

  

  观察 logcat 中的打印语句;

  由于 NormalActivity 已经把 MainActivity 完全遮住了,因此  onPause()  方法和  onStop()  方法都会执行;

  然后,按下 Back 键返回,观察 logcat 中的打印语句;

  由于之前 MainActivity 进入了停止状态,所以  onRestart()  方法会执行;

  之后又依次开始执行  onStart() 方法和  onResume()  方法;

  注意此时不会执行  onCreate()  方法,因为 MainActivity 并没有被重新创建;

  然后,点击第二个按钮启动 DialogActivity;

启动DialogActivity

  

  观察 logcat 中的打印语句;

  可以看到,只有  onPause()  方法得到了执行, onStop()  方法并没有执行;

  这是因为 DialogActivity 并没有完全遮挡住 MainActivity,此时,MainActivity 只是进入了暂停状态,并没有进入到停止状态;

  相应的,按下 Back 键返回,也应该只有  onResume()  方法执行;

  最后在 MainActivity 下按 Back 键退出程序,打印信息如下所示;

  依次会执行  onPausr() , onStop() , onDestroy()  方法,最终销毁 MainActivity;

Android 学习之活动的生命周期的更多相关文章

  1. android:activity活动的生命周期

    掌握活动的生命周期对任何 Android 开发者来说都非常重要,当你深入理解活动的生命 周期之后,就可以写出更加连贯流畅的程序,并在如何合理管理应用资源方面,你会发挥的 游刃有余.你的应用程序将会拥有 ...

  2. Android学习整理之Activity生命周期篇

    一.Activity生命周期说明   Activity的四种状态: ⒈活动状态(Active or Running):也称为运行状态,处于Activity栈顶,在用户界面中最上层,完全能被用户看到,能 ...

  3. android学习笔记28——Activity生命周期

    Activity生命周期 Activity的活动状态由android已Activity栈的形式管理,当前活动的Activity位于栈顶.随着不同应用的运行,每个Activity都有可能从活动状态转入非 ...

  4. Android学习笔记:Activity生命周期详解

    进行android的开发,必须深入了解Activity的生命周期.而对这个讲述最权威.最好的莫过于google的开发文档了. 本文的讲述主要是对 http://developer.android.co ...

  5. android学习笔记(5)Activity生命周期学习

    每一个activity都有它的生命周期,开启它,关闭它,跳转到其他activity等等,都会自己主动调用下面某种方法.对这些个方法覆写后观察学习. protected void onCreate(Bu ...

  6. Android学习手记(2) Activity生命周期

    1. 单个Activity的生命周期 当只有一个Activity的时候, 首先执行onCreate->onStart->onResume. 这时, 窗口便显示在屏幕上了. 然后我们按返回键 ...

  7. Android学习笔记----Activity的生命周期图示

    转载,一目了然.

  8. Android学习笔记(五)——活动的生命周期

    //此系列博文是<第一行Android代码>的学习笔记,如有错漏,欢迎指正! 为了能写出流畅连贯的程序,我们需要了解一下活动的生命周期. 一.返回栈 Android 中的活动是可以层叠的. ...

  9. Xamarin.Android活动的生命周期

    一.前言 用过Android手机的人一定会发现一种现象,当你把一个应用置于后台后,一段时间之后在打开就会发现应用重新打开了,但是之前的相关的数据却没有丢失.可以看出app的“生命”是掌握在系统手上的, ...

随机推荐

  1. Google PageSpeed Insights : 网站性能优化检测工具

    1 1 https://developers.google.com/speed/pagespeed/insights/ PageSpeed Insights 使您的网页在所有设备上都能快速加载. 分析 ...

  2. JavaScript for, for...in, for...of, for-await...of difference All In One

    JavaScript for, for...in, for...of, for-await...of difference All In One for for...in for...of for-a ...

  3. How to enable a local HTTPS website in macOS

    How to enable a local HTTPS website in macOS local SSL certificate http://loclahost:8888 https://loc ...

  4. koa-router all in one

    koa-router all in one holy shit , WTF, which is the true koa-router! MMP, 哪一个是正确的呀,fuck 找半天都晕了! koa- ...

  5. 微信小程序-生命周期图解

    微信小程序-生命周期图解 小程序生命周期 App 生命周期 https://developers.weixin.qq.com/miniprogram/dev/reference/api/App.htm ...

  6. Cookie 政策

    Cookie 政策 合规/隐私协议 https://www.synology.cn/zh-cn/company/legal/cookie_policy Cookie Cookie 政策 生效日期:20 ...

  7. mysql一张表到底能存多少数据?

    前言 程序员平时和mysql打交道一定不少,可以说每天都有接触到,但是mysql一张表到底能存多少数据呢?计算根据是什么呢?接下来咱们逐一探讨 知识准备 数据页 在操作系统中,我们知道为了跟磁盘交互, ...

  8. C++算法代码——众数

    好久没更新了-- 题目来自:http://218.5.5.242:9018/JudgeOnline/problem.php?id=1615 题目描述 N 个 1 到 30000 间无序数正整数,其中 ...

  9. 配置安装oh-my-bash

    背景 最近项目上有用到petalinux,所以只能在bash环境下使用命令行,所以不能使用oh-my-zsh 之前看一个dalao用oh-my-bash来规避这个问题.所以这里试一下安装oh-my-b ...

  10. 几个小实践带你快速上手MindSpore

    摘要:本文将带大家通过几个小实践快速上手MindSpore,其中包括MindSpore端边云统一格式及华为智慧终端背后的黑科技. MindSpore介绍 MindSpore是一种适用于端边云场景的新型 ...