Android开发之程序活动单元Activity【1】
迪丽瓦拉
2024-06-03 08:42:11
0

文章目录

  • 前言
  • 一 Activity简介
  • 二 Activity的生命周期
    • 2.1 Activity的声明周期状态
    • 2.2 Activity声明周期方法
  • 三 Activity的创建、配置、开启和关闭
    • 3.1 Activity的创建
    • 3.2 Activity的配置
    • 3.3 Activity的开启和关闭
  • 四 活动之间传递消息(Intent&IntentFilter)
    • 4.1 Intent简介
    • 4.2 显式Intent
    • 4.3 隐式Intent
    • 4.4 IntentFilter
      • 4.4.1 action属性匹配规则
      • 4.4.2 data属性匹配规则
      • 4.4.3 category属性匹配规则
  • 五 Activity的启动模式
    • 5.1 默认启动模式 standard
    • 5.2 栈顶复用模式 singleTop
    • 5.3 栈内复用模式 singleTask
    • 5.4 全局唯一模式 singleInstance
    • 5.5 综合示例
    • 5.6 动态设置启动模式
      • 5.6.1 FLAG_ACTIVITY_NEW_TASK
      • 5.6.2 FLAG_ACTIVITY_SINGLE_TOP
      • 5.6.3 FLAG_ACTIVITY_CLEAR_TOP

前言

  • 本文学自宁传奇老师,仅供学习和参考,禁止用作任何商业用途!

一 Activity简介

  • Android中的四大组件分别是活动Activity、服务Service、内容提供器ContentProvider、广播接收器BroadercastReceiver
  • Activity是一个负责和用户交互的组件、每个Android应用中都会用Activity来显示界面以及处理界面上一些控件的时间

二 Activity的生命周期

2.1 Activity的声明周期状态

  • Activitiy的生命周期是指Activity从创建到销毁的整个过程,分别分为:启动状态、运行状态、暂停状态、停止状态和销毁状态。
  • 启动状态 :Activity的启动状态很短暂,一般情况下,当Activity启动之后便会进入运行状态。
  • 运行状态:Activity在此状态时处于界面最前端,它是可见、有焦点的,可以与用户进行交互,如点击界面中的按钮和在界面上输入信息等。
  • 暂停状态:在某些情况下,Activity对用户来说仍然可见,但它无法获取焦点,用户对它操作没有响应,此时它就处于暂停状态。例如,当前Activity上覆盖了一个透明或者非全屏的界面时,被覆盖的Activity就处于暂停状态。
  • 停止状态:当Activity完全不可见时,它就处于停止状态。如果系统内存不足,那么这种状态下的Activity很容易被销毁。
  • 销毁状态:当Activity处于销毁状态时,将被清理出内存。
  • 当Activity处于运行状态时,Android会尽可能地保持这种状态,即使出现内存不足的情况,Android也会先销毁恚底的Activity,来确保当前Activity正常运行。
  • 需要注意的是,Activity生命周期的启动状态和销毁状态是过渡状态,Activity不会在这两个状态停留。

2.2 Activity声明周期方法

方法说明
onCreate:创建活动此时会把页面布局加载进内存,进入了初始状态。
onStart:开启活动此时会把活动页面显示在屏幕上,进入了就绪状态。
onResume:恢复活动此时活动页面进入活跃状态,能够与用户正常交互,例如允许响应用户的点击动作、允许用户输入文字等。
onPause:暂停活动此时活动页面进入暂停状态(也就是退回就绪状态),无法与用户正常交互。
onStop:停止活动此时活动页面将不在屏幕上显示。
onDestroy:销毁活动此时回收活动占用的系统资源,把页面从内存中清除掉。
onRestart:重启活动处于停止状态的活动,若想重新开启的话,无须经历onCreate的重复创建过程,而是走onRestart的重启过程。
onNewIntent:重用已有的活动实例
  • 图解
    在这里插入图片描述
  • 如果一个Activity已经启动过,并且存在当前应用的Activity任务栈中,启动模式为singleTask,singleInstance或singleTop(此时已在任务栈顶端),那么在此启动或回到这个Activity的时候,不会创建新的实例,也就是不会执行onCreate方法,而是执行onNewIntent方法。

在这里插入图片描述

三 Activity的创建、配置、开启和关闭

3.1 Activity的创建

  • 创建和配置非常简单,只需右键选择并填写相关内容即可
    在这里插入图片描述
  • 分别填写Activity名称、布局名称和报名即可
    在这里插入图片描述

3.2 Activity的配置

  • 新建的Activity需要在Androidmanifest.xml文件中配置组件
  • 如果Activity所在的包名和Androidmanifest.xml文件中标签中package属性指定的包名一致。android:name的属性可以直接设置为.Activity组件名


3.3 Activity的开启和关闭

  • 创建Activity的方法:startActivity()Intent参数是Android应用中各个组件之间通信的桥梁。
public void startActivity(Intent intent)
new Intent(this, ActFinishActivity.class)
  • 关闭Activity的方法:无参方法finish()
public void finish()
  • 示例
public class MainActivity2 extends AppCompatActivity implementsView.OnClickListener{@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main2);findViewById(R.id.button).setOnClickListener(this);}@Overridepublic void onClick(View view) {finish();}
}

四 活动之间传递消息(Intent&IntentFilter)

  • 如果用户需要从一个活动切换到另一个活动,则必须使用Intent来进行切换

4.1 Intent简介

  • Intent【意图】:程序中各组件间进行交互的一种重要方式。它不仅可以指定当前组件要执行的动作,还可以在不同组件之间进行数据传递。
  • Intent分为两类:显式Intent和隐式Intent
  • Intent用于Android各组件之间的通信,它主要完成下列3部分工作:
    1. 标明本次通信请求从哪里来、到哪里去、要怎么走
    2. 发起方携带本次通信需要的数据内容,接收方从收到的意图中解析数据
    3. 发起方若想判断接收方的处理结果,意图就要负责让接收方传回应答的数据内容
  • Intent的组成部分
元素名称设置方法说明与用途
ComponentsetComponent组件,它指定意图的来源与目标
ActionsetAction动作,它指定意图的动作行为
DatasetData即Uri,它指定动作要操纵的数据路径
CategoryaddCategory类别,它指定意图的操作类别
TypesetType数据类型,它指定消息的数据类型
ExtrasputExtras扩展信息,它指定装载的包裹信息
FlagssetFlags标志位,它指定活动的启动标志

4.2 显式Intent

  • 显式Intent:直接指定来源活动与目标活动,属于精确匹配
  • 在构建一个意图对象时,需要指定两个参数,第一个参数表示跳转的来源页面,即来源Activity.this;第二个参数表示待跳转的页面,即目标Activity.class
  • 具体的意图构建方式有如下3种:
  1. 在Intent的构造函数中指定
Intent intent = new Intent(this, ActNextActivity.class); // 创建一个目标确定的意图
  1. 调用意图对象的setClass方法指定
Intent intent = new Intent(); // 创建一个新意图
intent.setClass(this, ActNextActivity.class); // 设置意图要跳转的目标活动
  1. 调用意图对象的setComponent方法指定
Intent intent = new Intent(); // 创建一个新意图
// 创建包含目标活动在内的组件名称对象
ComponentName component = new ComponentName(this, ActNextActivity.class);
intent.setComponent(component); // 设置意图携带的组件信息

4.3 隐式Intent

  • 隐式Intent:没有明确指定要跳转的目标活动,只给出一个动作字符串让系统自动匹配,属于模糊匹配。Android系统会使用IntentFilter匹配相应的组件,匹配的属性主要包括以下 3个:
    • action:Intent对象要完成的动作
    • data:Intent对象中传递的数据
    • category:action添加的额外信息
  • 举例:
    1. 在清单文件AndroidManifest中配置Action
    
    
    
    1. 在其他的MainActivity中开启MainActivity2
    Intent intent = new Intent();
    intent.setAction("start_activity");
    startActivity(intent);
    
  • AndroidManifest.xml文件的Activity标签下的中,为被开启的Activity指定catrgory为"android.intent.category.DEFAULT"。必须在AndroidManifest.xml文件的Activity标签下的中,为被开启的Activity指定catrgory为"android.intent.category.DEFAULT"。
  • 通常App不希望向外部暴露活动名称,只给出一个事先定义好的标记串,这样大家约定俗成、按图索骥就好,隐式Intent便起到了标记过滤作用。这个动作名称标记串,可以是自己定义的动作,也可以是已有的系统动作。
  • 常见系统动作的取值
Intent 类的系统动作常量名系统动作的常量值说明
ACTION_MAINandroid.intent.action.MAINApp启动时的入口
ACTION_VIEWandroid.intent.action.VIEW向用户显示数据
ACTION_SENDandroid.intent.action.SEND分享内容
ACTION_CALLandroid.intent.action.CALL直接拨号
ACITON_DIALandroid.intent.action.DIAL准备拨号
ACTION_SENDTOandroid.intent.action.SENDTO发送短信
ACTION_ANSWERandroid.intent.action.ANSWER接听电话
  • 隐式Intent还用到了过滤器的概念,把不符合匹配条件的过滤掉,剩下符合条件的按照优先顺序调用。譬如创建一个App模块,AndroidManifest.xml里的intent-filter就是配置文件中的过滤器。像最常见的首页活动MainAcitivity,它的activity节点下面便设置了action和category的过滤条件。其中android.intent.action.MAIN表示App的入口动作,而android.intent.category.LAUNCHER表示在桌面
    上显示App图标,配置样例如下:


4.4 IntentFilter

  • 当发送一个隐式Intent后,Android系统会将它与程序中的每一个组件的过滤器进行匹配,匹配的属性有action、data、category,需要这三个属性都匹配成功才能唤起相应的组件。接下来,对三个属性的匹配规则进行介绍:

4.4.1 action属性匹配规则

  • action属性用来指定Intent对象的动作,在清单文件中设置action属性的示例代码如下:


  • 标答中间可以罗列多个action属性,但是当使用隐式Intent激活组件时,只要Intent携带的action与其中一个标签中action的声明相同,action属性就匹配成功。
  • 需要注意的是,在清单文件中为Activity添加标签时,必须添加action属性,否则隐式Intent无法开启该Activity.

4.4.2 data属性匹配规则

  • data属性用来指定数据的URI或者数据MIME类型,它的值通常与Intent的action属性有关联。


  • 标签中间可以罗列多个data属性,每个data属性可以指定数据的MIME类型和URI。其中,MIME类型可以表示image/ipegvideo/*等媒体类型。
  • 隐式Intent携带的data数据只要与IntentFilter中的任意一个data声明相同,data属性就匹配成功。

4.4.3 category属性匹配规则

  • category属性用于为action添加额外信息,一个IntentFilter可以不声明category属性,也可以声明多个category属性,在清单文件中设置category属性的示例代码如下:


  • 隐式Intent中声明的category必须全部能够与某一个IntentFilter中的category匹配才算匹配成功。需要注意的是,IntentFilter中罗列的category属性数量必须大于或者等于隐式Intent携带的category属性数量时,category属性才能匹配成功。如果一个隐式Intent没有设置category属性,那么他可以通过任何一个IntentFilter(过滤器)category匹配。

五 Activity的启动模式

  • app从第一个活动跳到第二个活动,接着结束第二个活动就能返回第一个活动,可是为什么不直接返回桌面呢?这要从Android的内核设计说起了,系统给每个正在运行的App都分配了活动栈,栈里面容纳着已经创建且尚未销毁的活动信息。鉴于栈是一种先进后出、后进先出的数据结构,故而后面入栈的活动总是先出栈,假设3个活动的入栈顺序为:活动A→活动B→活动C,则它们的出栈顺序将变为:活动C→活动B→活动A,可见活动C结束之后会返回活动B,而不是返回活动A或者别的地方。
  • 假定某个App分配到的活动栈大小为3,该App先后打开两个活动,此时活动栈的变动情况如图:
    在这里插入图片描述
  • 然后按下返回键,依次结束已打开的两个活动,此时活动栈的变动情况如图
    在这里插入图片描述
  • 前述的出入栈情况仅是默认的标准模式,实际上Android允许在创建活动时指定该活动的启动模式,通过启动模式控制活动的出入栈行为。
  • App提供了两种办法用于设置活动页面的启动模式:
    • 其一是修改AndroidManifest.xml,在指定的activity节点添加属性android:launchMode,表示本活动以哪个启动模式运行
    • 其二是在代码中调用Intent对象的setFlags方法,表明后续打开的活动页面采用该启动标志


在这里插入图片描述

5.1 默认启动模式 standard

  • 该模式可以被设定,不在 manifest 设定时候,Activity 的默认模式就是 standard。在该模式下,启动的 Activity 会依照启动顺序被依次压入 Task 栈中:

在这里插入图片描述

5.2 栈顶复用模式 singleTop

  • 在该模式下,如果栈顶 Activity 为我们要新建的 Activity(目标Activity),那么就不会重复创建新的Activity
    在这里插入图片描述

  • 应用场景:适合开启渠道多、多应用开启调用的 Activity,通过这种设置可以避免已经创建过的 Activity 被重复创建,多数通过动态设置使用。

5.3 栈内复用模式 singleTask

  • singleTop 模式相似,只不过 singleTop 模式是只是针对栈顶的元素,而 singleTask 模式下,如果task 栈内存在目标 Activity 实例,则将 task 内的对应 Activity 实例之上的所有 Activity 弹出栈,并将对应 Activity 置于栈顶,获得焦点。
    在这里插入图片描述
  • 应用场景:程序主界面
  • 对于那些及其耗费系统资源的Activity,我们可以考虑将其设为 singleTask模式,减少资源耗费

5.4 全局唯一模式 singleInstance

  • 在该模式下,我们会为目标 Activity 创建一个新的 Task 栈,将目标 Activity 放入新的 Task,并让目标Activity获得焦点。新的 Task 有且只有这一个 Activity 实例。 如果已经创建过目标 Activity 实例,则不会创建新的 Task,而是将以前创建过的 Activity 唤醒。
    在这里插入图片描述

5.5 综合示例

  • Activity3 设置为singleInstanceActivity1Activity2 默认(standard)。
  • 下图程序流程中,黄色的代表 Background的Task,蓝色的代表 Foreground 的Task。返回时会先把 Foreground 的Task 中的 Activity 弹出,直到 Task 销毁,然后才将 BackgroundTask 唤到前台,所以最后将Activity3 销毁之后,会直接退出应用
    在这里插入图片描述

5.6 动态设置启动模式

  • Manifest中通过launchMode属性设置的,称为静态设置,动态设置是通过 Java 代码设置的。
  • 通过 Intent 动态设置 Activity启动模式
intent.setFlags();
  • 如果同时有动态和静态设置,那么动态的优先级更高

5.6.1 FLAG_ACTIVITY_NEW_TASK

Intent.FLAG_ACTIVITY_NEW_TASK
  • 此 Flag 跟 singleInstance 很相似,在给目标 Activity 设立此 Flag 后,会根据目标 Activity 的 affinity 进行匹配,如果已经存在与其affinity 相同的 task,则将目标 Activity 压入此 Task。反之没有的话,则新建一个 task,新建的 task 的 affinity 值与目标 Activity 相同,然后将目标 Activity 压入此栈。
  • 但它与 singleInstance 有不同的点,两点需要注意的地方:
    • 新的 Task 没有说只能存放一个目标 Activity,只是说决定是否新建一个 Task,而 singleInstance模式下新的 Task 只能放置一个目标 Activity。
    • 在同一应用下,如果 Activity 都是默认的 affinity,那么此 Flag 无效,而 singleInstance 默认情况,也会创建新的 Task。

5.6.2 FLAG_ACTIVITY_SINGLE_TOP

  • 此 Flag 与静态设置中的 singleTop 效果相同
  • 该模式比较简单,对应Flag如下:
Intent.FLAG_ACTIVITY_SINGLE_TOP

5.6.3 FLAG_ACTIVITY_CLEAR_TOP

Intent.FLAG_ACTIVITY_CLEAR_TOP
  • 当设置此 Flag 时,目标 Activity 会检查 Task 中是否存在此实例,如果没有则添加压入栈。如果有,就将位于 Task 中的对应 Activity 其上的所有 Activity 弹出栈,此时有以下两种情况:
    • 如果同时设置 Flag_ACTIVITY_SINGLE_TOP ,则直接使用栈内的对应 Activity
    intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP |Intent.FLAG_ACTIVITY_SINGLE_TOP);
    
    • 没有设置,则将栈内的对应 Activity 销毁重新创建。

相关内容