活动的生命周期

了解活动的声明生命很重要,了解后你可以写出流畅的程序。

并且在合理管理应用资源方面更好发挥。

更好的用户体验

android的活动的可以层叠的

每次启动一个新活动就会覆盖原来的。

然后点击back键可以销毁当前的。上一次的就会出现。

其实Android是使用任务(Task)来管理。

一个任务就是一组存放在栈里的活动的集合。

这个栈被称为返回栈(Back Task)

栈是一种后进先出的数据结构。

默认情况下,每当启动一个新活动,它就会入栈。并放在栈顶。

当我们按返回键或者执行了finish的时候。处于栈顶的活动就被销毁。然后前一个入栈的活动就会重新返回栈顶。系统总会显示处于栈顶的活动给用户。

活动状态

每个活动在气什么周期中最多可能会有四种状态。

1 运行状态:

处于栈顶 ,系统不愿意回收否则用户体验差。

2 暂停状态

不处于栈顶,但是仍然可见。比如当前活动弹出一个对话框活动,对话框活动只占一部分屏幕。类似模态框。系统也不愿意回收这种,因为让用户看到很不友好。

3 停止状态

当一个活动不处于栈顶并且不可见。就进入停止状态。系统仍会为这种活动保存相应的状态和成员变量,但是这并不可靠,如果七天地方需要内存,系统也会考虑回收这种活动。

4 销毁状态

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

活动的生存期和七个回调方法

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

说白了 这七个回调函数 在声明周期的某个时候回触发 然后执行这些代码

比如创建的时候触发onCreate

下面介绍这七个方法。

onCreate:

活动第一次创建的时候调用,可以完成活动的初始化,比如加载布局 绑定按钮事件。

onStart:

由不可见变成可见的时候触发。

onResume:

这个方法在活动准备好和用户进行交互的时候调用,此时的活动处于返回栈的栈顶,并且处于运行状态。(活动已经被用户看到了)

onPause:

系统准备去启动或者恢复另外一个活动的时候调用。通常这个方法中会将一些消耗cpu的资源释放掉。以保存一些关键数据,但是这个方法的执行速度一定要快。不让回影响到新的栈顶活动的使用。(当前活动马上要隐藏 进入下一个活动但是还没进入)

onStop:

在活动完全不可见的时候调用,它和onPause的主要区别是,如果启动的新活动是一个对话框活动则onPause会执行,而onStop不会(活动被隐藏,然后新活动出现)

onDestory:

活动被销毁之前调用,之后活动的状态变成销毁状态。

onRestart:

活动由停止状态变为运行状态之前调用。也就是活动呗重新启动。

三种生存期

上面七个方法,除了onRestart 其他的都是两两相对。所以可以把活动晖为三种生存期。

1 完整生存期

活动从onCreate到onDestory方法之间所有的经历 就是完整生存期。

2 可见生存期:

从onStart到onStop之间所经历的。就是可用生存期。活动对用户总是可见的。可以通过这两个方法合理管理资源。比如onStart对资源进行加载,onStop对资源进行释放,从而保证处于停止状态的活动不要占用过多资源

3 前台生存期

活动从onResume到onPause之间所经历的叫前台生存期。活动总是处于运行状态。此时活动是可以和用户进行交互的。我们平常看到和接触最多的就是这种状态下的活动。

打开主活动->进入普通活动->返回主活动->返回桌面

05-12 15:32:43.899 4316-4316/com.foxdevelop.www.lifedemo E/主活动日志: onCreate:
05-12 15:32:43.926 4316-4316/com.foxdevelop.www.lifedemo E/主活动日志: onStart:
05-12 15:32:43.930 4316-4316/com.foxdevelop.www.lifedemo E/主活动日志: onResume:
05-12 15:33:00.973 4316-4316/com.foxdevelop.www.lifedemo E/主活动日志: onPause:
05-12 15:33:01.078 4316-4316/com.foxdevelop.www.lifedemo E/普通活动日志: onCreate:
05-12 15:33:01.079 4316-4316/com.foxdevelop.www.lifedemo E/普通活动日志: onStart:
05-12 15:33:01.081 4316-4316/com.foxdevelop.www.lifedemo E/普通活动日志: onResume:
05-12 15:33:02.969 4316-4316/com.foxdevelop.www.lifedemo E/主活动日志: onStop:
05-12 15:34:01.747 4316-4316/com.foxdevelop.www.lifedemo E/普通活动日志: onPause:
05-12 15:34:01.779 4316-4316/com.foxdevelop.www.lifedemo E/主活动日志: onRestart:
05-12 15:34:01.779 4316-4316/com.foxdevelop.www.lifedemo E/主活动日志: onStart:
05-12 15:34:01.780 4316-4316/com.foxdevelop.www.lifedemo E/主活动日志: onResume:
05-12 15:34:02.749 4316-4316/com.foxdevelop.www.lifedemo E/普通活动日志: onStop:
05-12 15:34:02.750 4316-4316/com.foxdevelop.www.lifedemo E/普通活动日志: onDestroy:
05-12 15:35:26.827 4316-4316/com.foxdevelop.www.lifedemo E/主活动日志: onPause:
05-12 15:35:28.534 4316-4316/com.foxdevelop.www.lifedemo E/主活动日志: onStop:
05-12 15:34:01.779 4316-4316/com.foxdevelop.www.lifedemo E/主活动日志: onDestroy:

项目实践

我们创建一个新的项目来体验一下声明周期

活动名称 我们就叫LifeDemo

添加一个EmptyActivity主活动

再添加两个普通活动NormalActivity和DialogActivity

然后修改它们的布局

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="普通活动" />

</LinearLayout>Code language: HTML, XML (xml)
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="对话框活动" />

</LinearLayout>Code language: HTML, XML (xml)

它们布局视图出来内容不同 其他基本一样

我们还需要把DialogActivity活动改为对话框活动

在AndroidManifest.xml修改

<activity android:name=".NormalActivity" />
<activity android:name=".DialogActivity" android:theme="@style/Base.Theme.AppCompat.Dialog"/>
</application>Code language: HTML, XML (xml)

给DialogActivity设为对话框

主活动布局

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent">

    <Button
        android:id="@+id/button"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="打开普通活动" />
    <Button
        android:id="@+id/buttondialog"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="打开对话框活动" />
</LinearLayout>Code language: HTML, XML (xml)

给主活动的两个按钮添加事件

package com.foxdevelop.www.lifedemo;

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

public class MainActivity extends AppCompatActivity {
    private static final String TAG = "MainActivity";
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Button b = (Button)findViewById(R.id.button);
        b.setOnClickListener(
                new View.OnClickListener(){
                    @Override
                    public void onClick(View view){
                        Intent it = new Intent(MainActivity.this,NormalActivity.class);
                        startActivity(it);
                    }
                }
        );
        Button b2 = (Button)findViewById(R.id.buttondialog);
        b2.setOnClickListener(
                new View.OnClickListener(){
                    @Override
                    public void onClick(View view){
                        Intent it = new Intent(MainActivity.this,DialogActivity.class);
                        startActivity(it);
                    }
                }
        );
    }

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

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

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

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

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

    @Override
    protected void onRestart() {
        super.onRestart();
        Log.e(TAG, "onRestart: ");
    }
}Code language: JavaScript (javascript)

1 运行程序

主活动创建会依次执行onCreate onStart onResume

点击打开普通活动按钮,此时触发onPause和onStop

因为NormalActivity把MainActitivity挡住了 所以这两个方法都会执行。

点击Back键返回

因为之前MainActivity已经进入了停止状态,所以会触发onRestart 之后又依次onStart和onResume

但是onCreate方法是不会执行的 因为它并没有重新创建,其实这个时候NormalActivity应该是触发了它自己的onDestroy

再点击打开对话框按钮

这个时候 触发了onPause

可以看到 并没有触发onStop

那是因为DialogActivity

并没有完全被遮挡住

同样 此时按下back

也只有onResume被执行。因为它并没有stop 所以不会触发onstart

我们可以看出 这个时候 会触发onPause onStop 然后销毁onDestory

Caused by: java.lang.IllegalStateException: You need to use a Theme.AppCompat theme (or descendant) with this activity.Code language: CSS (css)

主活动创建-对话框活动打开-返回主活动-返回桌面

05-13 02:10:51.635 4206-4206/com.foxdevelop.www.lifedemo E/主活动: onCreate: //创建新活动
05-13 02:10:51.673 4206-4206/com.foxdevelop.www.lifedemo E/主活动: onStart: //从不可见到可见
05-13 02:10:51.701 4206-4206/com.foxdevelop.www.lifedemo E/主活动: onResume: //活动可见了
05-13 02:12:01.993 4206-4206/com.foxdevelop.www.lifedemo E/主活动: onPause: //从当前活动要去其他活动
05-13 02:12:02.115 4206-4206/com.foxdevelop.www.lifedemo E/对话框活动: onCreate:
05-13 02:12:02.116 4206-4206/com.foxdevelop.www.lifedemo E/对话框活动: onStart:
05-13 02:12:02.143 4206-4206/com.foxdevelop.www.lifedemo E/对话框活动: onResume:
05-13 02:14:26.078 4206-4206/com.foxdevelop.www.lifedemo E/对话框活动: onPause: //按back键 要返回主活动
05-13 02:14:26.367 4206-4206/com.foxdevelop.www.lifedemo E/主活动: onResume: //主活动直接出现,因为没有stop 所以没有restart和start
05-13 02:14:26.803 4206-4206/com.foxdevelop.www.lifedemo E/对话框活动: onStop: //对话框活动不可见了
05-13 02:14:26.803 4206-4206/com.foxdevelop.www.lifedemo E/对话框活动: onDestroy: //因为是back或者finish所以它就要销毁
05-13 02:16:23.959 4206-4206/com.foxdevelop.www.lifedemo E/主活动: onPause:
05-13 02:16:25.606 4206-4206/com.foxdevelop.www.lifedemo E/主活动: onStop:
05-13 02:16:25.609 4206-4206/com.foxdevelop.www.lifedemo E/主活动: onDestroy: //任何的销毁之前 都要pause stopCode language: JavaScript (javascript)

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注