Android学习笔记1————Activity的生命周期和启动模式

Android学习笔记1————Activity的生命周期和启动模式

一.目录

二.Activity的生命周期

1.与Activity生命周期相关的七个函数

onCreate(): 表示Activity正在被创建,这是生命周期的第一个方法,在这个方法中我们可以做一些初始化工作,比如调用setContentView去加载界面布局资源,初始化Activity所需数据

onRestart(): 表示Activity正在重新启动。一般情况下,当当前Activity从不可见,重新变成可见状态时,onRestary就会被调用。这种情况一般是用户行为所导致的,比如按Home键切换到桌面,或者用户打开一个新的activity,这时当前的Activity就会暂停,也就是onPause和onStop被执行了,接着用户又回到这个Activity,就会出现这种情况

onStart(): 表示Activity正在被启动,即将开始,这时Activity已经可见了,但还是没有出现在前台,还无法和用户交互。这个时候其实可以理解为Activity已经显示,但我们还看不到。

onResume(): 表示Activity已经可见了,并且出现在前台并开始活动。要注意和onStart()的对比,onStart和onResume都表示Activity已经可见,但是onStart()的时候Activity还在后台,onResume()的时候Activity才显示出来。

onPause(): 表示Activity正在停止,正常情况下,紧接着onStop就会被调用。在特殊情况下,如果这个时候快速回到当前的Activity,那么onRestart就会被调用,这种情况下属于极端情况,用户操作很难重现这一幕。此时可以做一些存储数据和停止动画的操作,但注意不能太耗时,因为这会影响新Activity的显示,onPause()先执行完,新的onResume才会执行。

onStop(): 表示Activity即将停止,可以做一些稍微重量级的回收工作,同样不能太耗时。

onDestroy(): 表示Activity即将被销毁,这是Activity生命周期中最后一个回调,在这里我们可以进行一些回收工作和最终的资源释放。

2.典型情况下的生命周期分析

这里写图片描述

  1. 针对一个特定的Activity,第一次启动,回调如下:onCreate->onStart->onResume;
  2. 当用户打开新的Activity或者切换到桌面时,回调如下:onPause->onStop。这里有一种特殊情况,如果新Activity采用了透明主题,那么当前Activity不会回调onStop;
  3. 当用户再次回到原Activity时,回调如下:onRestart->onStart->onResume
  4. 当用户back键回退时,回调如下:onPause-> onStop -> onDestroy
  5. 当Activity被系统回收后再次打开,生命周期方法回调过程和1一样,注意只是生命周期方法一样,不代表所以过程都一样。

从整个生命周期来说,onCreate和onDestroy是配对的,分别标识着Activity的创建和销毁,并且只能又一次调用。从Activity是否可见来说,onStart和onStop是配对的,随着用户的操作或者设备屏幕的点亮和熄灭,这两个方面可能被调用多次;从Activity是否在前台来说,onResume和onPause是配对,随着用户的操作或者设备屏幕的点亮和熄灭,这两个方面可能被调用多次。

3.异常情况下的生命周期分析

  1. 系统配置变化导致Activity销毁重建
    这种情况比较典型的就是竖屏突然转换为横屏,由于系统配置发生改变,Activity就会销毁并重新创建。
    这种情况下的Activity的生命周期,如图:
    这里写图片描述
    当Activity被销毁时,它的onPasuse,onStop,onDestoy均会被调用。但同时由于是异常情况终止的,系统在onStop之前回调用onSavaInstanceState来保存当前Activity的状态,它和onPause没有一定的时序关系。当Activity被重新创建后,系统在onStart之后调用onRestoreInstanceState来恢复之前保存的数据。.
    保存数据的过程:Activity调用onSavaInstanceState去保存数据。然后Activity去委托Window去保存数据,紧接着window去委托他上面的顶级容器去保存数据,最后顶级容器去委托它的子元素来保存数据。

  2. 资源内存不足导致低优先级的Activity被杀死
    Activity的优先级:①前台Activity ②可见但非前台的Activity ③后台Activity(执行了onStop)
    当系统内存不足,系统会按照上述优先级回收目标Activity所在的进程,并在后续通过onSaveInstanceState和onRestoreInstanceState来恢复和存储数据。

  3. 指定Activity中的configChanges属性,使系统配置发生变化时,不重建Activity
    在AndroMenifest.xml的Activity声明configChanges的值,可以在系统配置发生改变时,使系统不会重建该Activity。常用的
    configChanges属性:locale(设备本地位置发生变化) orientation(屏幕方向发生变化)和keyboardHidden()这三个选项。

三.Activity的启动模式、

Activity目前一共有4种启动模式,分别是:standard,singleTop,singleTask,singleInstance.

1.standard

标准模式,是Activity的默认启动模式,在不显示指定的情况下,所有活动都会自动使用这种启动模式,这种模式下,没启动一个新的Activity,他就会在任务栈中入栈,并处于栈顶位置,并不在乎任务栈中是否存在相同实例。

standard模式下。Activity的onCreate,onStart,onResume均会被调用。

2.singleTop

栈顶复用模式:在这种模式下,如果新Activity已经处于任务栈栈顶,那么此Activity就不会被重新创建。

在singleTop模式下,Activity的onNewIntent方法会被回到,通过此方法的参数可以取出当前请求的信息。在这个Activity的onCreate,onStart不会被系统调用,因此它并不会发生什么变化。如果新的Activity存在但不存在与栈顶,那么新的Activity依然会重建。

3. singleTask

栈内复用模式:这是一种单实例模式,这种模式下,只要Activity在一个栈内存在,那么多次启动此Activity都不会重新实例。

在singleTask模式下,和singlTop一样,系统也会回调其onNewIntent方法,一个具有singleTask模式的Activity请求启动后,系统首先会寻找A想要的任务栈,如果不存在,就重新创建一个任务栈,然后创建A的实例后,把A放到栈内。如果存在A所需的任务栈,这时就要看A是否栈内有实例,如果有实例存在,那么系统就会把A调到栈顶并调用onNewIntent方法,同时把A上面的所有Activity退栈,如果实例不存在,就创建A的实例并把A压入栈中。

4. singleInstance

单实例模式:这是一种加强的singleTask模式,他除了具有singleTask模式的所有特性之外,还加强了一点,在这种模式下的Activity只能单独处于一个任务栈中。如果ActivityA是singleInstance模式,当A启动后,系统会为它新建一个任务栈。然后A独自在这个任务栈中

5. 任务栈

在singleTask模式中提到了任务栈,任务栈由参数TaskAffinity决定,这个参数标识了一个Activity所需要的任务栈的名字。默认情况下,所有Activity所需的任务栈名字为应用的包名。

6.启动方式的设置

  1. 通过AndroidMenifst中指定
<activity android:name=".MainActivity"
    android:screenOrientation="portrait"
    android:launchMode="singleTop">
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
</activity>
  1. 在Intent中通过标志位指定
Intent intent = new Intent();
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);

7.Activity常用Flags

  1. FLAG_ACTIVITY_NEW_TASK
    这个标记位作用是为Activity指定“singleTask”启动模式
  2. FLAG_ACTIVITY_SINGLE_TOP
    这个标记位作用是为Activity指定“singleTop”的启动模式
  3. FLAG_ACTIVITY_CLEAR_TOP
    具有此标记位的Activity,当他启动时在同一个任务栈中所有位于他上面的Activity都有出栈。
  4. FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS
    具有此标志的Activity,不会出现在历史Activity中

四.IntentFilter的区配规则

1. 概述

Activity的启动分为显示和隐式调用。隐式调用需要匹配目标组件的IntentFilter组件的所设的过滤信息,如果不匹配将无法启动目标Activity。IntentFilter中的过滤信息包括,action,category,data。
例:
这里写图片描述
一个过滤列表可以有多个action,cotegory,data,所有的action,cotegory,data分别构成不同类别,同一类别可以共同约束当前类别的匹配过程。只有一个Intent同时可以匹配action类别,category类别,data类别,才算完全匹配,只有完全匹配才能成功启动目标Activity。另外,一个Activity中可以有多个intent-filter,一个Intent只要能够匹配任意一组intent-filter即可成功启动相应的Activity。

2.action的匹配规则

action的匹配规则: intent中的action必须能够和过滤规则中的action匹配,即和字符串值完全一样。一个过滤规则中可以有多个action,那么只要Intent中的action能够和过滤规则中的任意一组相同即匹配成功

注意的点:

  1. action是一个字符串,系统预定义了一些action,同时也可以自定义自己的action。
  2. Intent中如果没有指定ction,那么匹配失败
  3. action区分大小写

3. category的匹配规则

category的匹配规则 :如果Intent中如果含有category,那么所有的category都必须和过滤规则中的其中一个category相同。即,如果Intent中如果出现了category,不管有几个category,对于每个category都必须是过来规则中存在的。

注意的点
1. Intent中可以不指定category,不指定时,也可以匹配成功,
2. 系统在调用startActivity或者StartActivityForResult会默认为Intent加上”abdroid.intent.category.DEEAULT”这个category。所以为了我们的Activity能够隐式调用Activity,就必须在intent-filter中指定“abdroid.intent.category.DEEAULT”指定category。

4. data的匹配规则

  • data的语法

    <data android:scheme = "string" 
    android:host = "string"
    android:port = "string"
    android:path = "string"
    android:pathPattern = "string"
    android:pathPrefix="string"
    android:mimeTYpe = "string"/>

    data由两部分组成,mimeType和URI。
    mimeType指3媒体类型,比如image/jpeg,video等等
    URI:

    • 结构:< scheme >://< host >:< port >/[ < path > | < pathPrefix > | < pathpattern > ]
    • 例:content://com.exaple:project:200/folder/subfolde/etc http://www.baidui.com:80/search/info
    • scheme:URI的模式,比如http,file,content等,如果URI没有指定scheme,那么这个URI无效
    • Host :URI的主机名,比如www.baidu.com,如果host未指定,那么整个URI也是无效
    • port:URI的端口号
    • path,pathPrefix,pathpattern:这3个表示路径信息,其中path表示完整路径信息,path表示完整路径信息,pathpattern也表示完整信息,但是他的可以包含通配符。pathPrefix表示路径的前缀信息
  • data的匹配规则
    data的匹配规则和action类似。它也要求Intent中必须含有data数据,并且data数据能够完全匹配过滤规则中的某一个data。

5.判断是否有Activity能够相应我们的隐式的intent

判断是否有Activity能够响应我们的intent有两种方法:PackageManager的resolveActivity方法或者Intent的resolvActivity方法,如果找不到匹配的Activity就会返回null。

五.参考资料

《Android艺术开发探索》
《第一行代码》

猜你喜欢

转载自blog.csdn.net/qq_38499859/article/details/80384421