《Android 开发艺术探索》学习笔记之Activity生命周期和启动模式

一、Activity生命周期分析

  • Activity在onStart()的时候还在后台,onResume()的时候才显示到前台。
  • 在新Activity启动之前,栈顶的Acticity需要先onPause()后,才执行新Activity的onCreate(),因此不能在onPause()中执行耗时的操作,尽量在onStop中做耗时的操作。
    • onStop()不能确定具体执行时间
异常情况下的生命周期分析:
  • 1、资源相关的系统配置发生改变导致Activity被杀死并重新创建
    • 保存:销毁时调用onSaveInstanceState()
      • 保存的是Bundle对象
      • 调用时机是在onStop之前,与onPause没有既定的时序关系
      • 只有在异常关闭才会调用,比如突然横屏,正常如调用finish()的时候不会调用
    • 取出:重新创建后调用onRestoreInstanceState()
      • 取出onSaveInstanceState()保存的Bundle对象,传递给onRestoreInstanceState()和onCreate()。
      • onRestoreInstanceState()在调用时机在onStart()之后
      • 两个方法二选一进行恢复,官方建议onRestoreInstanceState()。区别是onRestoreInstanceState()中的Bundle对象savedInstanceState一定是有值的,而onCreate()中的为null。
    • 保存流程
      • 委托思想:上层委托下层、父容器委托子元素
      • Activity首先调用onSaveInstance,然后委托Window保存数据,Window委托它上面的顶级容器(ViewGroup,一般是DecorView),然后再一一通知子元素保存数据。
  • 2、资源内存不足导致低优先级的Activity被杀死

    • Activity优先级从高到低依次为:
      • 前台Activity,优先级最高
      • 可见但非前台Activity
      • 后台Activity,如执行了onStop()的activity,优先级最低
    • 因此后台工作不适合放在Activity中,最好放在Service中并保证进程有一定的优先级。
    • 给Activity指定configChange属性可以避免在某项内容发生改变的时候系统重新创建Activity,而是调用Activity的onConfigurationChanged()方法
      //避免Activity在屏幕旋转的时候重新创建
      
      android:configChanges="orientation"

二、Activity的启动模式

①可通过AndroidManifest指定

②可通过在Intent中设置标志位指定(优先级较第一种高)

intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
1、Activity的LaunchMode
  • (1)standard:标准模式
    • 典型的多实例实现
    • 新启动的Activity会默认进入启动他的Activity所属的任务栈
    • 只有Activity类型的Context才有任务栈。当遇到ApplicationContext或ServiceContext启动Activity时,使用FLAG_ACTIVITY_NEW_TASK标记位创建一个新的任务栈,该Activity实际是以singleTask模式启动的
  • (2)singleTop:栈顶复用模式
    • 如果新Activity已经位于栈顶时,不会创建新的实例,回调onNewIntent()方法。
  • (3)singleTask:栈内复用模式
    • 是一种单实例模式
    • 当Activity实例已存在时,同样不会创建新实例,将该实例顶到栈顶,将原先在上方的Activity全部出栈(后进先出原则),并回调onNewIntent()方法。
      • 首先寻找是否存在待启动Activity想要的任务栈,有的话直接入栈,没有的话就创建一个新的并入栈。(即标准模式中的例子)
        • TaskAffinity标识所需任务栈的名字,默认情况下为应用包名,其值为字符串,中间必须有包名分隔符“.”。主要与allowTaskReparenting属性一起使用,如果该属性为true,则Activity可跨进程进入其他栈。
      • 然后看栈中是否有没有相同的实例。
    • 默认具有ClearTop属性
  • (4)singleInstan:单实例模式
    • 一种加强的singleTask模式,具有singleTask模式所有特性
    • 具有此种模式的Activity只能单独的位于一个任务栈中,启动该栈中Activity时,会将整个任务栈提前
2、Activity的Flags
  • FLAG_ACTIVITY_NEW_TASK
    • 具有此标记位的Activity启动模式为singleTask
  • FLAG_ACTIVITY_SINGLE_TOP
    • 具有此标记位的Activity启动模式为singleTop
  • FLAG_ACTIVITY_CLEAR_TOP
    • 具有此标记位的Activity,在启动时会将同一个栈中位于它上面的Activity全部出栈
    • standard模式启动的Activity具有此标记时,如果该Activity在栈中已存在,会将它连同它之上的Activty全部出栈,然后创建新的实例
    • singleTask启动模式默认具有此标记位的效果
  • FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS
    • 具有这个标记位的Activity不会出现在历史Activity列表中,等同于指定Activity属性Android:excludeFromRecents=”true”

三、IntentFilter的匹配规则

启动Activity的隐式调用需要Intent能够匹配目标组件的IntentFilter中所设置的过滤信息。只有**同时匹配**action、category、data类别,才能成功启动Activity。

  • 一个Activity中可以有多个IntentFilter,只要匹配一个就能启动对应的Activity。
1、aciton匹配规则

action是一个字符串,区分大小写。匹配是指字符串值完全一样
- 可以设置多个,至少有一个、只要有一个相同即匹配
- 如果没有指定action,则匹配失败

2、category匹配规则

category也是一个字符串。
- 默认匹配成功。系统调用startActivity或startActivityForResult的时候,默认为Intent加上android.intent.category.DEFAULT
- 每一个指定的category都必须相同才匹配

3、Data的匹配规则
  • Data由两部分组成

    • mimeType:媒体类型
    • URI:默认值为content和file

      • Scheme:URI的模式,必须指定
      • Host:URI的主机名,必须指定
      • Port:URI的端口号
      • 路径信息
        • path:完整路径信息
        • pathPattern:完整路径信息,可包含通配符“*”
        • pathPrefix:路径前缀信息
          //格式
          <scheme>://<host>:<port>/[<path>|<pathPrefix>|<pathPattern>]
          
          //示例
          http://www.baidu.com:80/search/info
  • 匹配规则:至少有一个,只要有一个相同就匹配
  • 使用 intent.setDataAndType() 方法为Intent指定完整的data
检测Activity是否能匹配隐式Intent
  • PackageManager或Intent的resolveActivity(Intent intent, int flags);
    • 返回最佳匹配的信息,找不到匹配则返回null
  • PackageManager的queryIntentActivities(Intent intent, int flags);
    • 返回所有成功匹配的Activity信息,找不到匹配则返回null
  • flag标记位使用MATCH_DEFAULT_ONLY:匹配所有category中带有default的Activity,即能够接收隐式Intent的Activity,只要不返回null,确保startActivity成功。
标志入口Activity
<action android:name="android.intent.action.MAIN" />

<category adnroid:name="android.intent.category.LAUNCHER" />

你可能感兴趣的:(Android开发艺术探索)