Activity的启动与管理之图记表查

Activity 作为AndroidApp重要的组成之一,它的创建、运行和维护也是我们必须知悉的一部分;Activity的创建是由开发人员决定,它的运行与维护则由系统通过任务栈进行协助管理,我们通过配置指定的启动模式来实现我们App的良好使用
Activity启动与管理.jpg

Activity的管理——任务栈

任务栈

Android Task 是用来存放Activity实例的容器,Android系统可以通过Task可以有序的对每个Activity进行管理,决定与用户交互的Activity(也就是栈顶的Activity)

  • Android Task是一个栈结构,只有压栈、出栈的操作,具有先进后出的特点
  • 启动一个Application的时候,系统会为它默认创建一个对应的Task,用来放置根Activity,这里需要注意一个App可以不止拥有一个任务栈,一个任务栈可以存放来不同应用的Activity
  • 任务栈所有的Activity被移除时才会被销毁,任务栈也可以移至后台并保留栈内所有的Activity及状态信息
  • 前台栈与后台栈,正在与用户交互的Activity存在的任务栈即为前台栈,其他则为后台栈,假设每个App只有一个任务栈,当我们切换使用APP时可以看到多个任务栈在后台,正在使用的APP的栈则是前台栈,当发生跳转其他应用时,后台栈被移动至前台成为前台栈,此时的返回操作则由前台栈接手,注意依然是两个栈

前台栈切换.png

Activity的启动模式

正常情况下,当一个Activity启动了另一个Activity的时候,新启动的Activity就会置于任务栈的顶端,并处于活动状态,启动它的Activity压入,处于停止状态,当用户按下返回键或者调用finish()方法时,系统会移除顶部Activity,让后面的Activity恢复活动状态,而不正常情况下就是给Activity设置特殊的启动模式使得我们的Activity跳转有了自定义的管理

模式说明补充
Standard/标准模式可存在多个实例,跳转到该Activity时会重新实例化并路由Intent给它默认进入启动它的任务栈中(在5.0之前新启动的Activity实例会放入发送Intent的Task的栈的顶部,5.0之后,上述情景会创建一个新的Task,新启动的Activity就会放入刚创建的Task中)
SingleTop/栈顶唯一可存在多个,只当跳转时该Activity存在栈顶时进行复用,其他情况下会进行重新实例化比如在某些情况下跳转某个Activity的操作发生了多次,使用这中模式就可以避免创建多个该Activity;默认任务栈同standard模式
SingleTask/栈内唯一不存在多个,该Activity在一个栈内存在时不会被重新创建例如App的登录界面,在退出到登录界面时,使用该模式可以不用对其他登录后的Activity做出栈操作而是自动清空原来之上的所有Activity
SingleInstance/栈内唯一不存在多个,该Activity存在单独的栈内,且不存在其他Activity,不存在时进行实例化并存放至单独的栈内新建栈来存放,例如拨号界面

Activity的配置启动

Activity的启动模式可以通过清单文件和使用Intent设置Activity Flags来配置。

  1. AndroidManifest配置 android:launchMode="standard/singleTop/singleTask/singleInstance"
  2. 设置 Activity Flags 配置
  • 写法
Intent intent = new Intent(SActivity.this, STestActivity.class); 
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
  • Activity Flags
属性名说明补充
FLAG_ACTIVITY_CLEAR_TASK清空当前task中的Activity功能,必须要和Intent.FLAG_ACTIVITY_NEW_TASK一起用受到安卓版本号的限制,在Api 11以上才可以起作用
FLAG_ACTIVITY_NEW_TASK使用一个新的Task来启动一个Activity,但启动的每个Activity都将在一个新的Task该Flag通常使用在从Service中启动Activity的场景,由于Service中并不存在Activity栈,所以使用该Flag来创建一个新的Activity栈,并创建新的Activity实例
FLAG_ACTIVITY_SINGLE_TOP使用singletop模式启动一个Activity与指定android:launchMode="singleTop"效果相同。
FLAG_ACTIVITY_CLEAR_TOP使用SingleTask模式来启动一个Activity,与指定android:launchMode="singleTask"效果相同。
FLAG_ACTIVITY_NO_HISTORYActivity使用这种模式启动Activity,当该Activity启动其他Activity后,该Activity就消失了,不会保留在Activity栈中。
FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS具有这个标记的Activity将不会出现在历史Activity列表中

带返回的启动Activity方法——StartActivityForResult

开发当中Activity与Activity的数据交互是通过Intent来进行,但普通的startActivity是没办法拿到将要启动的页面的交互后的数据,例如进入拍照页面后获取拍到的相片,因此Android这里设计了StartActivityForResult这一方法满足这一需求

  • 使用界面跳转
//REQUEST_CODE 为大于0小于65535(0xFFFF)的整数,
Intent intent = new Intent(this, XXXActivity.class); 
startActivityForResult(intent,REQUEST_CODE);
  • 使用界面的接收
@Override 
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
//requestCode 用于判断是否启动哪个Activity的返回结果
//resultCode  与Activity.RESULT_CANCELED、Activity.RESULT_OK判断是否取成功
//data     传递数据的载体
}
  • 跳转界面的返回
Intent data = new Intent(); 
setResult(Activity.RESULT_OK, data);
finish();

补充说明

  • 开发艺术与探索中提到使用非Activity类型的context(ApplicationContext)启动标准模式的Activity会报错,这是因为此时无法确认新建的Activity所存放的栈,可以为此Activity指定FLAG_NEW_ACTIVITY_TASK标记位来避免报错
  • REQUEST_CODE的大小限制是源码中校验规则限制,一旦超出范围则会抛出异常
/**
 * Checks whether the given request code is a valid code by masking it with 0xffff0000. Throws * an {@link IllegalArgumentException} if the code is not valid.
 */ 
 static void checkForValidRequestCode(int requestCode) {
  if ((requestCode & 0xffff0000) != 0) {
  throw new IllegalArgumentException("Can only use lower 16 bits for requestCode");
  } }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值