Activity生命周期和和启动模式

Android生命周期

Android的生命周期我们分为常规的运行时候的生命周期方法的解释和非常规的情况下调用的一些生命周期方法来做笔记。

Android常规生命周期

Android的生命周期有我们这里不再累赘,直接看到官方文档的图片示例。


Android生命周期图

  • onCreate:系统创建Activity的时候调用这个方法,在这里调用setContentView()来指定当前Activity要使用的布局文件。

  • onStart:Activity正在被启动,但是当前的activity还没有在前台运行,可以认为当前Activity没有获取到焦点无法与用户进行交互。

  • onRestart:表示Activity正在重新启动中,例如用户按住Home键返回桌面Activity会不可见调用onPause()和onStop()方法,再回到这个Activity会调用这个方法,并且后面会接着调用onStart()方法。

  • onResume:Activity从后台变为前台应用,获得焦点,用户可以和Activity进行交互。

  • onPause:Activity正在开始停止正常的步骤是下面的onStop()方法会被执行,注意在启动一个新的Activity的时候这个方法必须先执行完,新的Activity的onResume()方法才会接着执行,所以在这里不要做耗时的操作,会影响下一个Activity打开的速度。

  • onStop:应用即将要停止。如果 Activity 恢复与用户的交互,则后接 onRestart(),如果 Activity 被销毁,则后接onDestroy()。

  • onDestroy:Activity即将要销毁,在这里做一些资源回收的操作。

下面通过代码来验证下面几个知识点:

  1. 一个显示的Activity按住Home键:onPause()->onStop(), 再点击回来当前Activity:onRestart()->onStart()->onResume

  2. 用户按下back键:onPause()->onStop()->onDestroy().

  3. 当前Activity启动另一个Activity的时候要等当前的onPause()方法执行完毕了再执行下一个Activity的onResume()方法。

    代码为最简单的在生命周期里面打印日志

package com.testyelimin.test;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;

public class FirstActivity extends AppCompatActivity {
    private static final String TAG = "FirstActivity";
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_first);
        Log.i(TAG, "onCreate: ");
    }

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

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

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

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

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

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

验证知识点1按住home键日志如下:


这里写图片描述

从桌面再次进入应用:


这里写图片描述

验证知识点2点击back键:


这里写图片描述

验证知识点3从当前activity启动另外一个activity,当前Activity的onPause()执行完毕以后才会执行下一个activity的onResume():


这里写图片描述

可以看到当前的activity的onPause()方法执行完毕了再执行启动下一个Activity的onCreate()->onStart()->onResume()方法,最后再执行当前activity的onStop()方法形成了一个闭环。我试了一下在当前Activity的onPause()方法中休眠两秒,下一个Activity会等待它执行完再启动,所以在onPause()方法中千万要避免耗时操作;另外从第二个Activity中按返回键同样会先执行第二个Activity的onPause()方法,然后回到第一个Activity的onRestart()->onStart()->onResume()方法,最后到第二个Activity的onStop()->onDestroy()再次形成一个闭环。

Activity异常的生命周期方法

上面描述的是正常使用操作的时候activity的生命周期方法,但是我们在操作的时候不正常的生命周期也是我们需要了解的知识点,主要了解onSaveInstanceState()方法和onRestoreInstanceState()方法的回调机制,以及系统在内存不足的时候对我们的activity的回收。

某种原因导致Activity杀死并且重新创建:

这种情况最好模拟的方式是使用手机突然横竖屏切换的时候出现。当对Activity的configChanges没有做任何配置的时候横屏切换为竖屏回调为:

这里写图片描述

  • 这里没有像网上多数描述的没有配置configChanges的时候竖屏切换为横屏回调两次生命周期方法。他们都只回调一次生命周期方法。

  • 当配置orientation和keyboardHide的时候同意都回调生命周期方法一次。

  • 当配置configChanges为orientation时很没用和上面一样完整的生命周期回调。但是onConfigurationChanged()方法会发生回调,这里我们可以利用这一点来处理视频界面的时候横竖屏切换的布局功能。

其中configChanges几个我们常用可以配置的参数的含义为:

项目含义
mcc国际移动用户识别码的国家代码,三位数字组成,中国为460
mnc国际移动用户识别码的运营商码,两位数组组成,中国联通为01
locale本地位置发生变化,一般指语言发生改变
touchscreen触摸屏幕发生改变
keyboard键盘类型发生变化,比如用户使用了外插键盘
keyboardHide键盘可访问性发生了变化,例如弹出了键盘
orientation屏幕方向发生了变化,例如旋转了屏幕
screenSize屏幕尺寸发生变化,旋转屏幕尺寸会变。当minSdkVersion和targetSdkVersion低于13时不会导致Activity重启,否则会重启。

内存不足导致Activity重启:

Android的进程分类以及内存管理在以后做记录,这里理解当系统运行内存不足的时候会根据回收算法回收掉一些内存,我们的Activity被这种方式回收的时候会回调onSaveInstanceState()和onRestoreInstanceState()方法来存储和恢复数据。

Activity启动模式

之所以会有启动模式的配置参数,它肯定有它的作用,Android的每个Activity的实例都放在任务栈中,这是一个”后进先出”的栈结构。如果多次重复打开Activity那么就把实例都压入栈中会造成很大的浪费,Android系统开发者早已经考虑到了这一点。可以提供多种模式供我们选择。

配置LaunchMode

  • standard:标准模式,默认的启动模式。它会启动一个实例压入栈中。同样回调正常的生命周期方法。例如Activity A通过启动标准模式的Activity B那么B会进入A的任务栈中。注意一点非Activity的Context没有任务栈,所以我们有时候在开发中会出现AndroidRuntimeException:Calling startActivity from outside of an Activity context requires the FLAG_ACTIVITY_NEW flag.这时我们要在启动的那个类添加上面的那个flag就可以正常运行了。这个配置会创建一个新的任务栈。
  • singleTop:栈顶复用模式。当配置这种启动模式的Activity位于栈顶,那么在此启动这个Activity的时候不会重复创建它,但是它的onNewIntent()方法会调用,onCreate()和onStart()不会调用,onPause()和onResume()会调用。注意当这个Activity已经存在不位于栈顶的时候,还是会正常的走回调创建Activity。
  • singleTask:栈内复用原则。当启动一个singTask模式的Activity,系统首先寻找是否有它启动的任务栈,没有则先建立任务栈。当存在任务栈并且含有Activity不会重复建立,会调用它的onNewInent()方法。注意如果这个Activity不位于栈顶,它会默认带一个clearTop的flag会清除上面的Activity。
  • singleInstance:单实例模式。当第一次创建会单独创建一个任务栈存放Activity,并且不会重复创建。

    注意Activity所需任务栈我们可以配置TaskAffinity属性来指定所需的任务栈,模式都是包名相同。

Activity Flag参数

在xml文件可以配置启动模式的参数,当使用代码启动Activity的时候可以在Intent中addFlag来配置Activity启动的参数的配置。

Flag含义
FLAG_ACTIVITY_NEW_TASK和在XML中配置启动模式singleTask一样
FLAG_ACTIVITY_SINGLE_TOP同singleTop
FLAG_ACTIVITY_CLEAR_TOP位于这个Activity栈顶的实例都会被清除。singleTask自带这个flag
FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS这个配置属可以让Activity不出现在最近任务列表中,注意只有栈的root Activity 才生效。

IntentFilter的匹配规则

我们上面描述通过代码设置显式的启动Activity,我们还可以通过匹配IntentFilter来隐式的启动Activity。当一个Activity配置了隐式启动的IntentFilter当显示启动还是以显示启动为主即使没有匹配IntentFilter,想要隐式启动要匹配上才可以启动。

一个Activity可以配置多组IntentFilter只要其中一组匹配成功则可以成功启动。而每组IntentFilter中主要是action,category,data三个匹配字段。每个字段都可以配置多个。当都配置了要匹配上才可以成功启动。action可以在Intent中配置多个只要有一个和XML配置上即可,category定义了的必须要在XML中都有定义才可以匹配上。data和action的匹配规则相同。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值