在这金三银四的时间里一个哥们忽然一本正经的问我Activity的启动模式和具体的应用模式;我也一想是啊,平是不太注意结果到了 关键的时刻卡壳了,感觉未雨绸缪一下,做个记录:

一、Activity四种启动模式:

(一)、基本描述
  1. standard:标准模式:如果在mainfest中不设置就默认standard;standard就是新建一个Activity就在栈中新建一个activity实例;
  2. singleTop:栈顶复用模式:与standard相比栈顶复用可以有效减少activity重复创建对资源的消耗,但是这要根据具体情况而定,不能一概而论;
  3. singleTask:栈内单例模式,栈内只有一个activity实例,栈内已存activity实例,在其他activity中start这个activity,Android直接把这个实例上面其他activity实例踢出栈GC掉;
  4. singleInstance :堆内单例:整个手机操作系统里面只有一个实例存在就是内存单例;
  • 在singleTop、singleTask、singleInstance 中如果在应用内存在Activity实例,并且再次发生startActivity(Intent intent)回到Activity后,由于并不是重新创建Activity而是复用栈中的实例,因此Activity再获取焦点后并没调用onCreate、onStart,而是直接调用了onNewIntent(Intent intent)函数;
(二)、taskAffinity属性

taskAffinity属性和Activity的启动模式息息相关,而且taskAffinity属性比较特殊,在普通的开发中也是鲜有遇到,但是在有些特定场景下却有着出其不意的效果。

taskAffinity是Activity在mainfest中配置的一个属性,暂时可以理解为:taskAffinity为宿主Activity指定了存放的任务栈[不同于App中其他的Activity的栈],为activity设置taskAffinity属性时不能和包名相同,因为Android团队为taskAffinity默认设置为包名任务栈。

taskAffinity只有和SingleTask启动模式匹配使用时,启动的Activity才会运行在名字和taskAffinity相同的任务栈中。

(三)、Intent中标志位设置启动模式

在上文中的四种模式都是在mainfest的xml文件中进行配置的,GoogleAndroid团队同时提供另种级别更高的设置方式,即通过Intent.setFlags(int flags)设置启动模式;

  1. FLAG_ACTIVITY_CLEAR_TOP : 等同于mainfest中配置的singleTask,没啥好讲的;
  2. FLAG_ACTIVITY_SINGLE_TOP: 同样等同于mainfest中配置的singleTop;
  3. FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS: 其对应在AndroidManifest中的属性为android:excludeFromRecents=“true”,当用户按了“最近任务列表”时候,该Task不会出现在最近任务列表中,可达到隐藏应用的目的。
  4. FLAG_ACTIVITY_NO_HISTORY: 对应在AndroidManifest中的属性为:android:noHistory=“true”,这个FLAG启动的Activity,一旦退出,它不会存在于栈中。
  5. FLAG_ACTIVITY_NEW_TASK: 这个属性需要在被start的目标Activity在AndroidManifest.xml文件配置taskAffinity的值【必须和startActivity发其者Activity的包名不一样,如果是跳转另一个App的话可以taskAffinity可以省略】,则会在新标记的Affinity所存在的taskAffinity中压入这个Activity。
  • 个人认为在上述Flag中FLAG_ACTIVITY_NEW_TASK是最为重要的一个flag,同时也需要注意的是网上有很多是瞎说的;而且也是个人唯一一个在实际开发中应用过的属性;先说说个人应用示例:
  • 1.在Service中启动Activity;
  • 2.App为系统Launcher时,跳转到微信无法退出时用到;

至于为啥看下文开发的案例就知道了。

(四)、startActivity场景

Activity的启动模式的应用的设置是和它的开发场景有关系的,在App中打开新的Activity的基本上分为两种情况:

  1. 目标Activity是本应用中的Activity,即它的启动模式是可以直接在fanifest中配置或者默认为standard,任务栈也可以自己随意设置;
  2. 目标Activity是第三方App中的Activity,这个时候就需要先考虑打开新Activity的是和自己App放在同一任务栈中还是新的task中【这个是很重要的因为在Android的机制中:同一个任务栈中的activity的生命周期是和这个task相关联的[具体实例见下文]】,然后考虑Activity的启动模式; 所以Android提供了优先级更高的设置方式在Intent.setFlags(int flags),通过这setFlags就可以为打开第三方的App中Activity设置任务栈和启动模式了,具体设置就自己去看源码了。

二、Activity四种启动模式常见使用场景:

这也是面试中最为长见的面试题;当然也是个人工作经验和借鉴网友博文,如有错误纰漏尽请诸位批评指正;

LauchMode Instance
standard 邮件、mainfest中没有配置就默认标准模式
singleTop 登录页面、WXPayEntryActivity、WXEntryActivity 、推送通知栏
singleTask 程序模块逻辑入口:主页面(Fragment的containerActivity)、WebView页面、扫一扫页面、电商中:购物界面,确认订单界面,付款界面
singleInstance 系统Launcher、锁屏键、来电显示等系统应用

三、启动模式在实际开发中小插曲

最近的项目就出现了一个由于启动模式导致的问题,先开还是一脸闷还是同事最先想到问题缘由于是做个记录长个教训吧。最近搞的App是在一个cpu比较low的Android系统的设备上跑的,而且是App是作为LAUNCHER启动的,并且在App的一个功能就是点击直接跳转到微信登录LauncherUI页[如果有登录会自动到聊天页面]的,这个听起也是很普通的一个功能。但是还是出了一个小问题。

(一)、问题复现

开机后App作为launcher启动,然后打开微信LauncherUI加载页【未登录微信】到微信登录页,然后点返回键【系统返回键】不能也退出微信返回到原来我们的launcher的App中去了,然后Android大法在底部导航栏中查看系统任务【有那些应用在后台】,结果显示一个也没有;这样就是一时间尴尬了退不出微信了;

(二)、问题定位:

1.点击返回键【系统返回键】微信页面没有退出:微信的登录页面Activity拦截了返回键 KeyEvent.KEYCODE_BACK 事件【只是将应用隐藏在后台不退出,然后回到桌面】,所以登录Activity没有销毁;
2.系统导航栏查看正在运行的应用为空,实际上是正在运行我们的App[launcher而且放在在system/app下]和微信的,两个问题缘由:

  1. 我们的App作为launcher被Android作为系统应用任务栈了所以没有显示;
  2. 微信是在launcherApp中打开的而且打开代码是并没有设置微信LauncherUI的启动模式和任务栈,Android默认是在同一个任务栈中了,所以在查看任务栈时看不到微信应用,而且由于App是launcher作为系统任务就显示没有应用程序了;
(三)、解决办法

我们的期望是即使不登录微信同样点返回键就可以直接返回到我们App的页面中;
根据已经点位到问题进行解决一个基本思路是:用户点返回键后杀死微信的Activity,回到我们App页面中;
具体代码就是

//修改之前Intent intent = new Intent();intent.setClassName("com.tencent.mm", "com.tencent.mm.ui.LauncherUI");context.startActivity(intent);
//修改之后是这样的Intent intent = new Intent();intent.setClassName("com.tencent.mm", "com.tencent.mm.ui.LauncherUI");intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);context.startActivity(intent);

其实代码中只是设置新打开微信在新的任务栈中,这样就是及时在微信LauncherUI的页面中拦截了返回键【只是将应用隐藏在后台不退出然后回到桌面】,这样我们App最为launcher,所以就回到我们App了。同样这样在在导航栏中查看真正运行任务就可以看到微信了;

(四) 、新的问题

在添加上Intent.FLAG_ACTIVITY_NEW_TASK之后是需要新建一个任务栈打开App的,虽然是解决了不能返回的问题,但是也引发新的问题:

 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK)

1.用户点返回键后微信并没有退出:在界面上看到是回到桌面App中了,其实微信并没有退出任然在后台运行;这个问题其实普遍存在,而且开发者基本上都是对用户采取理性欺骗【或者隐瞒】,现实中用户也是都已经接受;

2.点击跳转到微信明显卡顿:以前打开新的App是在一个任务栈中的,打开新App页面和在同一App页面跳转感觉基本上是一瞬间的,用户感觉不到是在App之间跳转的,设置Intent.FLAG_ACTIVITY_NEW_TASK之后是需要新建一个任务栈打开App的,点击后有明显的停顿【CPU越差劲越明显】用户体验明显变差了。

四、Activity中其他常见问题

(一) 生命周期

1.正常生命周期:
onCreat() onStart() onResume() onPause() onStop() onDestroy()

2.横竖屏切换
(1).未设置

configChanges:

(一) 、Intent的基本应用

在Android中Intent是在四大组件之间进行交互与通讯,也可以在应用之间通讯。其底层的通信是以Binder机制实现的,在物理层则是通过共享内存的方式实现的。

1.Intent属性

Intent的属性有:component(组件)、action、category、data、type、extras、flags;所有的属性也是各显神通,满足开发者的各种需要满足不同场景;
component: 显然就是设置四大组件的,将直接使用它指定的组件,借助这一属性可以实现不同应用组件之间通讯;
action: 是一个可以指定目标组件行为的字符串,开发人员可以自定义action通过匹配action实现组件之间的隐士跳转,当然Android系统也已经预定部分String作为系统应用Action,例如打开系统设置页面等等;
data: 通常是URI类型或者MIME类型格式定义的操作数据;表示与动作要操纵的数据

  • data中长见的MIME类型数据;
    tel://:号码数据格式,后跟电话号码。 
    mailto://:邮件数据格式,后跟邮件收件人地址。
    smsto://:短息数据格式,后跟短信接收号码。
    content://:内容数据格式,后跟需要读取的内容。 
    file://:文件数据格式,后跟文件路径。
    market://search?q=pname:pkgname:市场数据格式,在Google Market里搜
  • data中URI
    data元素组成的URI模型:scheme://host:port/path 例如:file://com.android.jony.test:520/mnt/sdcard;

Category: 属性用于指定当前动作(Action)被执行的环境;
type: 对于data范例的描写;
extras和flags 这两个太熟悉了就不在重复;

2.Intent的隐士与显示

显示Intent是最长见的,也是使用最为频繁的;但是很显然隐士Intent更为强的尤其是在模块化的时代;

(二) 、Activity异常生命周期与应用

这个过程中几个核心的函数和参数是:Bundle[onCreate(Bundle savedInstanceState)],onSaveInstanceState(Bundle outState)、onRestoreInstanceState(Bundle savedInstanceState)

1.系统配置改变引起异常;

这里的系统配置改变是指由于横竖屏切换等引起的Activity生命周期的变化,进而引发的资源的变化。在Android中系统配置改变是会引起Activity销毁重建的,例如横竖屏切换,只是切换时间差太小,用户眼睛不能察觉而已。activity重建的时候就在之前Activity销毁前,系统会先调用onSaveInstanceState(Bundle outState)存储当时各种状态,在新建Activity中Android会通过onRestoreInstanceState(Bundle savedInstanceState)读取数据并自动恢复到之前Activity的View,当然在Activity中开发者自己的代码逻辑就需要自己处理啦。

  • 触发onSaveInstanceState(Bundle outState)的条件:
    1、当用户按下HOME键时。
    2、从最近应用中选择运行其他的程序时。
    3、按下电源按键(关闭屏幕显示)时。
    4、从当前activity启动一个新的activity时。
    5、屏幕方向切换时(无论竖屏切横屏还是横屏切竖屏都会调用)。
  • 在前4种情况下,当前activity的生命周期为:
    onPause -> onSaveInstanceState -> onStop。
2.系统回收引起异常

在Android系统内存不足时,同时Activity失去焦点后被系统给回收后,Activity 再次被创建时,通过onSaveInstanceState 和onRestoreInstanceState来存储恢复数据再次显示在屏幕上之前的View等状态;

3.Activity异常基础处理

1.最常见的是在onCreate(Bundle savedInstanceState)中通判断savedInstanceState是否为空,恢复Activity中的数据体;
2.另一种就是根据应用场景在mainfest中配置各种参数尽可能减少由于配置参数引起的Activity异常;
3.使用onConfigurationChanged方法代替onRestoreInstanceState实现恢复数据逻辑,更高级的自然就是性能优化、实时监视的思路啦;

https://blog.csdn.net/freekiteyu/article/details/69523967

Activity的四种启动模式应用场景相关推荐

  1. Android Activity:四种启动模式,Intent Flags和任务栈(转自他人博客)

    在Android中每个界面都是一个Activity,切换界面操作其实是多个不同Activity之间的实例化操作.那各个页面跳转关系如何决定呢?如果启动了顺序启动了ABCD的Activiy,如何从D调回 ...

  2. Activity的四种启动模式-图文并茂

    1.对于使用standard 模式的活动,系统不会在乎这个活动是否已经在返回栈中存在,每次启动都会创建该活动的一个新的实例. 例如A启动A,A再接着启动A,A继续启动A,然后再分别出栈,如图所示 2. ...

  3. Activity的四种启动模式和onNewIntent()

    Android中Activity启动模式详解 在Android中每个界面都是一个Activity,切换界面操作其实是多个不同Activity之间的实例化操作.在Android中Activity的启动模 ...

  4. Android中Activity的四种启动模式

    每次看到这种专有词汇都十分佩服创造者的智慧,创造者一定和我一样都中二,我已然确信. 我写博客的目的,就是希望不断磨练自己,让自己能够不将一件简单的事情讲的复杂,让自己能将一件复杂的事情讲的简单.嘛嘛, ...

  5. 知识总结: Activity的四种启动模式

    通常情况下,一个应用有一个Task,这个Task就是为了完成某个工作的一系列Activity的集合.而这些Activity又被组织成了堆栈的形式.当一个Activity启动时,就会把它压入该Task的 ...

  6. 【Android笔记】Activity的四种启动模式

    在多Activity开发中,有可能是自己应用之间的Activity跳转,或者夹带其他应用的可复用Activity. 可能会希望一个Activity跳转到原来某个Activity实例,而不是产生大量重复 ...

  7. Android之Activity的四种启动模式

    当应用运行起来后就会开启一条线程,线程中会运行一个任务栈,当Activity实例创建后就会放入任务栈中.可以根据实际的需求为Activity设置对应的启动模式,从而可以避免创建大量重复的Activit ...

  8. Activity的四种启动模式

    standard:标准的启动模式,默认启动模式.启动一个activity就会创建该activity的实例. singleTop:如果启动的activity已经位于栈顶,那么就不会重新创建一个新的act ...

  9. Activity的四种启动模式区别

    (1) standard模式启动模式,每次激活Activity时都会创建Activity,并放入任务栈中.(2) singleTop如果在任务的栈顶正好存在该Activity的实例, 就重用该实例,否 ...

最新文章

  1. 【Spring】12、Spring Security 四种使用方式
  2. jquery ajax node,jquery ajax post json and node express
  3. 【转载】Linux系统挂载NTFS文件系统
  4. Val编程-读取汉字
  5. STM32 的 JLink 调试时「Flash Timeout」和「Flash Download Failed」问题解决
  6. Unity手游之路四3d旋转-四元数,欧拉角和变幻矩阵
  7. 石油采集(求联通区域) 2018多校寒假集训 (dfs+二分匹配)
  8. 零基础学python难_0基础学python有多难
  9. QQ浏览器怎么截取整个网页 QQ浏览器完整截取网页的方法
  10. 选择多级分类_② 供应商管理(分类、评估、选择、绩效、集成、供应商过多的对策、多级供应商管理)...
  11. C++-bit转hex(四位二进制转十六进制)
  12. Download PuTTY: latest release (0.75) pscp
  13. cad完全卸载教程_完全卸载CAD2012的步骤教程--系统之家
  14. 电信光猫超级密码破解
  15. 二元置信椭圆r语言_医学统计与R语言:Meta 回归作图(Meta regression Plot)
  16. vue echarts 实现速度的那种进度蓄力效果
  17. easyui mysql 分页_Easyui 树形网格添加分页_EasyUI 教程
  18. 单片机实验秒表设计程序c语言,如何使用单片机实现秒表的设计
  19. 【智慧家科教2023新春首训】东方昱老师畅谈新发展之路:前途是光明的 未来是可期的
  20. 凹凸技术揭秘 · Tide 研发平台 · 布局研发新基建

热门文章

  1. 华为模拟器的wlan配置
  2. 【前端部署第四篇】使用 Docker 构建缓存及多阶段构建优化单页应用
  3. 软浮点硬浮点不配套问题(error:uses VFP register arguments)
  4. DeepFM模型原理与案例实现
  5. 兴趣部落的前端性能优化实践概览
  6. 锐龙r5 4500u和i7 10510u 的区别
  7. 利用pyqt和mysql创建登入界面
  8. ●BZOJ 2149 拆迁队
  9. echarts取消绑定
  10. (85)如何编写仿真激励?