安卓Activity的生命周期篇章(一)

对于安卓开发而言,activity和activity的生命周期既是基础也是重中之重,真正理解了activity的生命周期才能娴熟的运用并开发出高质量的代码。(关于activity的认知可以看我上一篇文章安卓四大组件介绍)

一、Activity的状态
Activity/Running:
活动状态,即当前activity为用户可见并且可与用户进行交互。
Paused:
当activity失去焦点时,或打开一个非全屏的activity或被一个透明的activity置于栈顶时,此时activity处于Paused状态,是不可与用户交互的,但是该activity还是可见的并且其所有状态信息和成员变量都是保存不变的,除非系统内存紧张才会被系统回收。
Stopped:
当一个activity被另一个activity完全覆盖的情况下,被覆盖的activity就会进入stopped状态,并且变的不可见,但是跟Paused状态一样会保存所有状态信息和成员变量。
Killed:
当Activity被系统回收掉时,Activity就处于Killed状态。

二、Activity的生命周期
1.生命周期一览:

相信很多人都看过这张生命周期图,先给大家混个眼熟,后面我们将围绕这张图进行分析。

2.典型的生命周期
所谓典型的生命周期就是在用户参与的情况下,activity经历创建、运行、停止、销毁的正常周期,下面首先介绍下几个主要生命周期方法的调用时机,然后在通过例子进行验证。

onCreate:该方法是在activity被创建的时候调用,它是第一个被调用的方法,我们在创建activity时一般都要重写这个方法,可以在此方法里面完成一些初始化操作,如:setContentView()设置界面布局资源,初始化一些所需的组件信息等。
onStart:创建完activity之后便要启动activity,此时该方法被调用,activity已处于可见状态,只是还没有在前台显示,因此无法与用户进行交互。可以简单理解为activity已显示而我们无法看见摆了。
onResume:此方法被调用时,说明activity处于前台可见了,可与用户进行操作。此时activity处于Activity/Running状态,它与onStart()方法的相同之处是两者都表示可见,只不过onStart()执行时activity还在后台不可与用户交互,而onResume()则已显示在前台可与用户交互,从前面的流程图可以看出,当activity停止的时候(onPause和onStop被执行),再重新回到前台时onResume()也会被执行,因此也可以在此方法中进行一些资源的初始化,比如重新初始化onPause方法中释放掉的一些资源。
onPause:回调此方法说明activity正在停止(Paused状态),一般来说紧接着会执行onStop()方法,但是看流程图,有可能onPause执行之后就执行onResume方法了,这种极端的情况可能是用户操作使当前Activity退居后台后又迅速地再回到当前的Activity,此时onResume方法就会被回调。当然在onPause方法中可以进行一些资源的释放以及停止动画或者数据存储等,但是不能太耗时,因为这可能会影响到新的Activity的显示——onPause方法执行完成后,新Activity的onResume方法才会被执行。
onStop:一般onPause方法执行之后会执行此方法,表示activity停止或完全被覆盖,此时activity处于后台不可见也不可与用户交互,在此方法里面也可以进行数据存储和资源释放(同样不能太耗时)。
onRestart:表示activity正在重新启动,也就是当activity由不可见变为可见状态时,该方法被调用。这种情况一般是用户打开一个新的activity,当前activity被停止,然后用户又重新回到当前activity,这是onRestart方法就会被回调。
onRestart:表示activity被销毁,这是activity生命周期中最后一个被执行的方法,因此可以在此方法中执行最后的资源释放和一些回收工作。

三、验证Activity的生命周期

package com.example.administrator.applicationtest;

import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;

public class FirstActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.d("Dreamer__YY:", "onCreate: ");
        setContentView(R.layout.activity_main);
    }

    public void toSecondActivity(View view) {
        Intent intent = new Intent(this,SecondActivity.class);
        startActivity(intent);
    }

    @Override
    protected void onRestart() {
        super.onRestart();
        Log.d("Dreamer__YY:", "onRestart: ");
    }

    @Override
    protected void onStart() {
        super.onStart();
        Log.d("Dreamer__YY:", "onStart: ");
    }

    @Override
    protected void onResume() {
        super.onResume();
        Log.d("Dreamer__YY:", "onResume: ");
    }

    @Override
    protected void onPause() {
        super.onPause();
        Log.d("Dreamer__YY:", "onPause: ");
    }

    @Override
    protected void onStop() {
        super.onStop();
        Log.d("Dreamer__YY:", "onStop: ");
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        Log.d("Dreamer__YY:", "onDestroy: ");
    }
}

1.我们先分析activity启动过程中的生命周期,启动一个activity运行程序日志截图如下:

从Log中我们可以看出Activity启动后,先调用了onCreate方法,然后是onStart方法,最后是onResume方法,进入运行状态,此时Activity已在前台显示。因此,
Activity启动–>onCreate()–>onStart()–>onResume()依次被调用。

2.当activity创建完成后,按下Home键返回桌面,运行日志截图如下:

我们在Activity创建完成后,点击Home回调主界面时,可以发现此时onPause方法和onStop方法被执行,也就是点击Home键回到主界面(Activity不可见)–>onPause()–>onStop()依次被调用。

3.当我们点击Home键回到主界面后,再次点击App回到Activity时,调用结果如下:

可以发现依次调用了onRestart、onStart、onResume方法,so,当我们再次回到原Activity时–>onRestart()–>onStart()–>onResume()依次被调用。

4.当我么在原有的activity基础上启动一个新的activity,运行日志如下:

我们可以看到原来的Activity调用的了onPause方法和onStop方法。也就是说
在原Activity的基础上开启新的Activity,原Activity生命周期执行方法顺序为–>onPause()–>onStop(),事实上跟点击home键是一样的。但是这里有点要注意的是如果新的Activity使用了透明主题,那么当前Activity不会回调onStop方法。同时我们发现新Activity(SecondActivity)生命周期方法是在原Activity的onPause方法执行完成后才可以被回调,这也就是前面为什么说在onPause方法不能操作耗时任务的原因了。

5.当我们按下返回键退出当前activity,运行日志截图如下:

当点击Back键回退时,相当于退出了当前Activity,Activity将被销毁,因此
退出当前Activity时–>onPause()–>onStop()–>onDestroy()依次被调用。

四、小结
1.onCreate和onStart之间有什么区别?
(1)可见与不可见的区别。前者不可见,后者可见。
(2)执行次数的区别。onCreate方法只在Activity创建时执行一次,而onStart方法在Activity的切换以及按Home键返回桌面再切回应用的过程中被多次调用。因此Bundle数据的恢复在onStart中进行比onCreate中执行更合适。
(3)onCreate能做的事onStart其实都能做,但是onstart能做的事onCreate却未必适合做。如前文所说的,setContentView和资源初始化在两者都能做,然而想动画的初始化在onStart中做比较好。

2.onStart方法和onResume方法有什么区别?
(1)是否在前台。onStart方法中Activity可见但不在前台,不可交互,而在onResume中在前台。
(2)职责不同,onStart方法中主要还是进行初始化工作,而onResume方法,根据官方的建议,可以做开启动画和独占设备的操作。

3.onPause方法和onStop方法有什么区别?
(1)是否可见。onPause时Activity可见,onStop时Activity不可见,但Activity对象还在内存中。
(2)在系统内存不足的时候可能不会执行onStop方法,因此程序状态的保存、独占设备和动画的关闭、以及一些数据的保存最好在onPause中进行,但要注意不能太耗时。

4.onStop方法和onDestroy方法有什么区别?
onStop阶段Activity还没有被销毁,对象还在内存中,此时可以通过切换Activity再次回到该Activity,而onDestroy阶段Acivity被销毁。

5.为什么切换Activity时各方法的执行次序是(A)onPause→(B)onCreate→(B)onStart→(B)onResume→(A)onStop而不是(A)onPause→(A)onStop→(B)onCreate→(B)onStart→(B)onResume
(1)一个Activity或多或少会占有系统资源,而在官方的建议中,onPause方法将会释放掉很多系统资源,为切换Activity提供流畅性的保障,而不需要再等多两个阶段,这样做切换更快。
(2)按照生命周期图的表示,如果用户在切换Activity的过程中再次切回原Activity,是在onPause方法后直接调用onResume方法的,这样比onPause→onStop→onRestart→onStart→onResume要快得多。

6.与生命周期密切相关的onSaveInstanceState方法和onRestoreInstanceState方法在什么时候执行?
通过阅读源码会发现,当targetSdkVersion小于3时onSaveInstanceState是在onPause方法中调用的,而大于3时是在onStop方法中调用的。
而onRestoreInstanceState是在onStart之后、onResume之前调用的。

你可能感兴趣的:(安卓基础知识)