Activity详解(二)——Activity的四种启动模式

本文详细介绍了Android中Activity的四种启动模式:Standard、singleTop、singleTask及singleInstance,并解析了TaskAffinity的作用及其与启动模式的关系。此外还讨论了如何为Activity指定启动模式以及一些标志位的使用。

一、前言

在学习Activity启动模式之前,我们先来简单了解一下Activity栈:栈都是先进后出的,Activity栈也不例外,启动一个Activity,系统就会创建一个Activity的实例放入到Activity栈中,当销毁一个Activity的时候,系统就会从Activity栈中移除掉相应的Activity实例。这里就会有一个问题,每次启动Activity都创建一个实例压入Activity栈中,就会消耗更多的内存,也不利于Activity的复用,所有就有了启动模式来规定Activity的启动方式。
可以用命名adb shell dumpsys activity来查看当前Activity栈中的Activity实例情况。

二、四种启动模式

1.Standard

标准启动模式。该启动模式为Activity启动的默认模式,也就是说我们平常创建一个Activity的时候,就是以这种模式启动。用这种模式启动的Activity会在它想要去的Activity栈中创建一个实例,而不论这个栈中是否已经含有这个Activity的实例。什么是它想要去的Activity栈呢?简单来讲,就是哪个Activity启动它的,它就会想去那个Activity所在的栈中。例如,Activity A启动了Activity B,而Activity A在ActivityA栈中,所以Activity B也就会想要去Activity A所在的栈——ActivityA栈中。

2.singleTop

栈顶复用模式。用该模式启动的Activity,如果在想要去的栈中的栈顶为该Activity的实例,那么就不会再次创建该Activity的实例,而是回调Activity的onNewIntent方法来做处理。需要注意的是,这个Activity的onCreate、onSt、方法不会被系统调用,因为它并没有发生改变。举个例子,假设目前有一个Activity栈,栈内的情况为ABCD,其中ABCD为四个Activity,A位于栈底,D位于栈顶,A、D的启动模式为SingeTop,这时候如果要启动D,那么栈内的情况依然是ABCD,如果要启动A,那么栈内的情况就会变成ABCDA。

3.singleTask

栈内复用模式。该模式和singleTop较为类似,用该模式启动的Activity,如果在想要去的栈中的栈顶为该Activity的实例,也同样不会再次创建该Activity的实例,而是调用onNewIntent。但是有一种不同,如果在该Activity栈中已经有了该Activity的实例(不是位于栈顶),那么系统就会复用该Activity的实例,把位于该Activity上面的其他Activity实例给清除掉,同时把该Activity调到栈顶来(把位于该Activity上面的其他Activity清除掉就相当于把该Activity调用栈顶了)。而singleTop模式的Activity,不会清除掉位于其上面的的其他的Activity实例。这是因为singleTask启动的Activity默认具有clearTop效果。还是用2中的那个例子,假设此时A、D的启动模式为singleTask,这时候如果要启动D,情况和2一样,依然是ABCD,而如果要启动A,那么栈内的情况就完全不一样了,变成了A,把A上面的Activity实例都clear掉了。注意,此时这个例子假设所有Activity想要去栈都是ABCD所在的栈,是因为TaskAffinity属性,至于为什么,后文再分析。

4.singleInstance

单实例模式。这种模式可以理解为是一种加强版的singleTask,利用该模式启动的Activity,如果系统中已经存在该实例,则会重用该Activity实例,然后回调onNewIntent方法;如果系统中还没有该Activity实例,则会创建一个新的Activity栈一个该Activity实例并把该Activity实例压入到栈中。这个栈有一个特点,就是只能容纳这个Activity,不能够容纳其他Activity实例,也就是说用该模式启动的Activity会独占一个Activity栈。

三、TaskAffinity

上文中数次说到Activity想要去的Activity栈为启动其的那个Activity所在的Activity栈。但是如果想把Activity启动到别的Activity栈内呢?这里需要用到一个参数:TaskAffinity,TaskAffinity可理解为喜爱的任务,也就是想去的Activity栈。通过给Activity指定TaskAffinity属性,可以改变Activity想要去的Activity栈,将Activity启动到TaskAffinity属性指定的Activity栈中。其实TaskAffinity标识的是一个Activity想要去的任务栈的名字,默认情况下,所有Activity想要去的Activity栈名字为应用的包名。通过指定与包名不同的名字,可以将Activity启动到别的栈去。这也解释了二.3中的那个疑问了。
注意:

  1. 该属性要和singleTask启动模式才有意义,和其他三种模式混在一起使用是没有意义的。因为其他三种启动模式启动的Activity都会运行在启动它的那个Activity所在的栈中,而singleTask启动模式启动的Activity会运行在TaskAffinity属性所指定的栈中。
  2. 这个TaskAffinity属性的值为类似包名格式的字符串(但要与包名不同),如包名为com.google,则TaskAffinity的值可为com.google1等等。

四、如何给Activity指定启动模式

1.通过AndroidManifest.xml为Activity指定启动模式,如下

<activity
    android:name="com.ryg.chapter_1.SecondActivity"
    android:configChanges="screenLayout"
    android:launchMode="singleTask"
    ..../>

2.在intent中设置标志位来为Activity设置启动模式

Intent intent = new Intent();
intent.setClass(MainActivity.this, SecondActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);

这两种启动方式的区别:
1. 优先级上,第二种的优先级要高于第一种方式,当两种方式都存在的时候,以第二种方式为准。
2. 作用范围不同,例如第一种方式不能够直接为Activity设定FLAG_ACTIVITY_CLEAR_TOP标识(清除上边Activity实例标识),而第二种方式不适合于singleInstance启动模式。

五、标志位

在上面第二种启动方式中,出现了一个Flags,Activity的Flags有很多,但是大部分情况下不需要使用标志位,所以了解一下即可。
有一个比较常见的Flags为FLAG_ACTIVITY_NEW_TASK,对于有在Service中启动Activity经验的童鞋们,大概都会遇到过这个错误:

Calling startActivity from outside of an Activity context requires the FLAG_ACTIVITY_NEW_TASK flag.

这个错误相信读者一定不会陌生,这是因为Activity会默认进入到启动它的Activity所在的Activity栈中,但是对于非Activity类型的Context(如Service)并没有所谓的Activity栈,此时就会出问题。解决方法是为待启动的Activity加上一个flags:FLAG_ACTIVITY_NEW_TASK,这是就会为待启动的Activity创建一个新的Activity栈。加上该flags启动的Activity实际上相当于用singleTask启动模式启动Activity。

六、结语

其实实际开发中,Activity的启动模式应用得不多,大部分都以默认的standard模式启动。但是我们还是需要了解其原理的,万一以后真的用到了呢。

内容概要:本文围绕微电网群的双层优化与分布式优化问题,提出基于交替方向乘子法(ADMM)的分布式协同优化控制策略,并通过Matlab代码实现仿真验证。研究构建了上层为微电网间能量协调与优化调度、下层为各微电网内部源-荷-储精细化运行管理的双层优化模型。采用ADMM算法将集中式优化问题分解为多个可并行求解的子问题,实现了计算的分布式化与信息隐私保护,显著提升了系统的可扩展性与鲁棒性。文中系统阐述了模型构建原理、ADMM算法设计流程及其收敛性分析,并通过仿真实验验证了该方法在降低系统综合运行成本、提高可再生能源消纳能力以及维持系统稳定运行方面的有效性。; 适合人群:具备电力系统分析、优化理论基础,熟悉Matlab编程,从事微电网、分布式能源系统、智能电网等领域研究的研究生、科研人员及工程技术人员。; 使用场景及目标:① 学习和掌握基于ADMM的分布式优化方法在微电网群协同能量管理中的具体应用;② 实现微电网群多主体参与下的经济调度与仿真分析;③ 深入理解双层优化架构的设计理念与分布式求解算法的实现机制。; 阅读建议:建议结合所提供的Matlab代码进行动手实践,重点剖析模型建立与算法实现的关键细节,可通过调整系统参数、改变运行场景等方式,深入探究ADMM算法的收敛特性及其对优化效果的影响。
内容概要:本文聚焦于风电出力不确定性的精确建模问题,提出采用拉丁超立方抽样(LHS)方法生成具有统计代表性的风电场景,并结合先进的场景缩减技术以降低计算复杂度。通过Matlab编程实现了LHS在高维随机变量空间中的均匀采样,有效克服了传统蒙特卡洛方法样本收敛慢、效率低的问题。在此基础上,引入基于聚类分析或概率距离度量的场景缩减算法,对初始大规模场景集进行优化合并,保留关键概率特征与出力趋势,构建出精简且具代表性的典型场景集。该方法显著提升了电力系统随机优化模型(如机组组合、储能调度、微电网能量管理)的求解效率与数值稳定性,同时确保输入场景的合理性与真实性,具备良好的可复现性与工程应用价值。; 适合人群:适用于具备一定电力系统分析基础和Matlab编程能力,从事新能源并网、随机规划、场景生成、电力市场及综合能源系统优化等方向研究的研究生、科研人员及工程技术人员。; 使用场景及目标:①掌握拉丁超立方抽样在风电不确定性建模中的理论原理与Matlab实现技巧;②学习并应用场景生成与缩减技术,提升随机优化问题的建模与求解效率;③为含高比例风电的电力系统调度、风险评估与决策分析提供高质量的输入场景支撑。; 阅读建议:建议读者结合所提供的Matlab代码逐模块调试运行,深入理解抽样策略、距离计算、聚类缩减等核心算法的实现细节,并尝试将其集成到具体的优化模型中进行验证与拓展,以强化科研实践能力与创新思维。
内容概要:本文围绕基于交替方向乘子法(ADMM)的多主体综合能源系统分布式协同优化展开研究,提出了一种利用ADMM算法实现多个能源主体间高效协同优化的解决方案。该方法将集中式优化问题分解为多个可并行求解的子问题,各主体在保护自身数据隐私的前提下,仅通过交换少量边界信息即可完成全局协同优化,有效解决了传统集中式方法存在的通信负担重、隐私泄露风险高等问题。研究涵盖了模型构建、算法设计、收敛性分析及仿真验证全过程,并以Matlab代码实现了算法原型,展示了其在提升系统运行效率、促进可再生能源消纳方面的潜力。该研究不仅提供了完整的算法实现框架,还深入探讨了ADMM在多区域电网、多微网及产消者等复杂场景下的适用性与扩展能力,为现代综合能源系统的分布式管理提供了理论依据和技术支持。; 适合人群:具备一定电力系统、优化理论及Matlab编程基础的研究生、科研人员或从事综合能源系统相关工作的工程技术人员。; 使用场景及目标:①应用于多区域电网、多微网、产消者(Prosumer)等多主体参与的综合能源系统协同调度;②实现数据隐私保护下的分布式优化,避免中心节点收集全局敏感信息;③学习ADMM算法在电力系统中的具体建模与实现方法,掌握其收敛特性与参数整定技巧。; 阅读建议:读者应结合提供的Matlab代码进行实践,重点关注ADMM算法的迭代流程、惩罚因子设定及其对收敛速度的影响,同时可通过修改系统规模与参数设置,进一步探究算法在不同场景下的适应性与性能表现。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值