Activity篇之启动模式与应用(五)

238 阅读4分钟

引言

Android LaunchMode是一个重要概念,它定义了Activity的启动模式,决定了Activity在不同情况下如何启动。

可通过在AndroidManifest.xml文件中配置,可以影响Activity的实例化和调用栈管理。

LaunchMode介绍

standard模式

  • 默认启动模式,每次启动都会新建Activity实例,并入任务栈顶
  • 适用于相互独立的页面

singleTop模式

  • 栈顶模式
  • 若启动的Activity已位于栈顶,则只回调onNewIntent,否则创建新Activity实例并入栈
  • 适用于保持单一实例的页面,避免重复创建
  • 例:用于通知详情页,当有多个通知时,无需为每个通知单独开启Activity

singleTask模式

  • 单任务栈模式(单例)
  • 若启动的Activity已位于栈中,则只回调 onNewIntent 并将其上的Activity实例移出任务栈,使其回至栈顶,否则新建Activity实例并入栈
  • 适用于音乐播放界面,确保只有一个播放界面
  • 适用于程序入口页面,确保整个应用只有一个首页Activity实例

例:浏览器主界面,无论多少应用打开浏览器都只会启动一个Activity实例,其余都在onNewIntent,并清空之前页面

singleInstance模式

  • 单例模式
  • 新任务栈中启动Activity,独占一个新的任务栈
  • 一旦存在该Activity实例,任何应用再次启动该Activity,都只回调onNewIntent
  • 效果与多个应用共享一个应用类似,无论哪个应用激活该Activity,都相当于进入共享应用中
  • 适用于全局单例的功能,与其他应用不共享任务栈
  • 例:闹钟提醒,闹钟提醒可能会不定时被启动,所以单独存在一个栈中比较合适

LaunchMode常见问题

  1. 如何在不同的任务栈中启动Activity?
  • 可通过设置Intent的FLAG_ACTIVITY_NEW_TASK标志位,在新任务栈启动Activity,若Activity已存在于其他任务栈,系统会将其移至新任务栈
val intent = Intent(this, DemoActivity::class.java)
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
startActivity(intent)
  1. LauchMode与Intent搭配使用时如何正确处理传输数据?
  • 使用Bundle传递数据。将数据封装至Bundle中,通过Intent传递,即使Activity被系统回收重建,也可保证数据恢复
  • 序列化对象。传递自定义对象,需实现序列化 SerializableParcelable,以便在不同实例间传递
  • singleTasksingleTop 模式需特别注意,在 onNewIntent 中处理
  • singleInstance 模式需特别注意,独立任务栈,可使用 广播共享文件 通信
  1. 如何使用LaunchMode实现应用内导航?
  • 关注点:singleTopparentActivityName
  • 子Activity启动模式设为singleTop,并通过parentActivityName属性指定父Activity
  • 父Activity启动模式为standard
  • 此时子Activity点击返回键,会跳转至父Activity
  1. 如何使用LaunchMode实现Activity单例?
  • 可使用 singleInstancesingleTask 实现
  • singleInstance会创建新任务栈,并成为任务栈的根Activity,再次启动移至任务栈前台,并执行onNewIntent
  • singleTask + taskAffinity属性,会创建新任务栈,并成为任务栈的根Activity,再次启动移至任务栈前台,并执行onNewIntent
  1. LaunchMode与taskAffinity属性关系?
  • taskAffinity属性可用来指定Activity所属的任务栈
  • taskAffinity属性未配置,默认栈为应用包名
  • taskAffinity指定栈存在,Activity添加至该任务栈
  • taskAffinity指定栈不存在,创建栈并将Activity添加至该任务栈
  • LaunchMode与taskAffinity共同决定Activity启动行为

例:LaunchMode为singleTask且taskAffinity与另一个Activity的taskAffinity相同时,该Activity启动时会将任务栈移至前台,并执行onNewIntent

  1. LaunchMode与Intent Flags如何巧妙搭配使用?
  • 使用FLAG_ACTIVITY_NEW_TASK可在新任务栈启动
  • 使用FLAG_ACTIVITY_CLEAR_TOP可清除该Activity上面的Activity
  • 使用FLAG_ACTIVITY_CLEAR_TASK可清除任务栈所有Activity,实现 回到主页重新登录 功能
  • singleTask + FLAG_ACTIVITY_NEW_TASK可创建新任务栈,可通过设置taskAffinity更加灵活的控制任务栈
  1. LaunchMode与FLAG_ACTIVITY_NEW_TASK有何区别?
  • LaunchMode用来指定Activity的启动模式
  • LaunchMode属于全局属性,对所有启动该Activity的Intent都有效
  • FLAG_ACTIVITY_NEW_TASK是Intent的标志位,指定是否在新任务栈中打开
  • LAG_ACTIVITY_NEW_TASK属于单次设置,只对当前启动Activity的Intent有效
  1. LaunchMode安全性问题如何预防?
  • 避免singleTasksingInstance模式下存储敏感信息,该实例可被多个任务或应用共享
  • 增加Intent数据验证,避免被恶意应用利用,尤其是FLAG_ACTIVITY_NEW_TASK等Flag使用时