美文网首页Android开发Android开发
Activity的启动与管理之图记表查

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

作者: Shimmer_ | 来源:发表于2019-04-08 22:51 被阅读0次
    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存在单独的栈内,且不存在其他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_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_HISTORY Activity使用这种模式启动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");
      } }
    

    相关文章

      网友评论

        本文标题:Activity的启动与管理之图记表查

        本文链接:https://www.haomeiwen.com/subject/kivzbqtx.html