位置: 编程技术 - 正文

[原]深刻理解activity启动模式,彻底理解android的四种启动模式,尤其singleTask(深入理解)

编辑:rootadmin

推荐整理分享[原]深刻理解activity启动模式,彻底理解android的四种启动模式,尤其singleTask(深入理解),希望有所帮助,仅作参考,欢迎阅读内容。

文章相关热门搜索词:深刻理解的意思是什么,深层理解,深刻理解什么意思,深刻理解什么意思,深层理解,深刻理解什么意思,深刻理解英文怎么说,深层理解,内容如对您有帮助,希望把文章链接给更多的朋友!

与界面跳转联系比较紧密的概念是Task(任务)和Back Stack(回退栈),activity的启动模式会影响Task和Back Stack的状态,Intent类中定义的一些标志(以FLAG_ACTIVITY_开头)和activity的属性taskAffinity也影响Task和Back Stack的状态。Task是一个存在于Framework层的概念,在android中,一个应用就是一组组件的集合android组件化程度极高,application是由四大组件组成的。在app安装时,系统会读取manifest的信息,将所有的组件解析出来,以便在运行时对组件进行实例化和调度。task是在程序运行时,只针对activity的概念,task是一组相互关联的activity的集合,它是存在于framework层的一个概念,控制界面的跳转和返回。这个task存在于一个称为back stack的数据结构中,也就是说,framework是以栈的形式管理用户开启的activity。这个栈的基本行为是,当用户在多个activity之间跳转时,执行压栈操作,当用户按返回键时,执行出栈操作。task是可以跨应用的,这正是task存在的一个重要原因。有的Activity,虽然不在同一个app中,但为了保持用户操作的连贯性,把他们放在同一个任务中,进程是操作系统内核中的一个概念,表示直接受内核调度的执行单位。java编写的应用程序,运行在dalvik虚拟机中,可以认为一个运行中的dalvik虚拟机实例占有一个进程,在默认情况下,一个应用程序的所有组件运行在同一个进程中,应用程序中的不同组件也可以运行在不同的进程中。只需要在manifest中用process属性指定组件所运行的进程的名字。如下所示:

一个Activity的Launch Mode为standard时,默认启动模式,在这种模式下启动的activity可以被多次实例化,每个新实例都会处理一个相应Intent对象。 一个Activity的Launch Mode为singleTop时,如果实例已经存在于任务桟的桟顶,那么再启动这个Activity时,不会创建新的实例,而是重用位于栈顶的那个实例,并且会调用该实例的onNewIntent()方法将Intent对象传递到这个实例中。以singleTop模式启动的activity的一个实例已经存在与任务桟中,但是不在桟顶,那么它的行为和standard模式相同,也会创建多个实例。 一个Activity的Launch Mode为singleTask时,在新建这个Activity时,默认taskAffinity情况下,一般不会新建task,taskAffinity属性默认application中是相同的,那么就会新建在当前栈。如果这个Activity已经在某个task的stack中了,此时只会调用它的onNewIntent(),而不会调用onCreate()。(谷歌的官方文档上称,如果一个activity的启动模式为singleTask,那么系统总会在一个新任务的最底部(root)启动这个activity,并且被这个activity启动的其他activity会和该activity同时存在于这个新任务中。如果系统中已经存在这样的一个activity则会重用这个实例,并且调用他的onNewIntent()方法。即,这样的一个activity在系统中只会存在一个实例。这种说法是不准确的,或者翻译的隔阂,已验证不是总会在栈底启动singletask的activity,已打印验证int taskId = getTaskId();命令行中执行以下命令 adb shell dumpsys activity )其实,把启动模式设置为singleTask,framework在启动该activity时只会把它标示为可在一个新任务中启动,至于是否在一个新任务中启动,还要受其他条件的限制。增加一个taskAffinity属性给启动的singleTask的aty,那么将在新task启动。 一个Activity的Launch Mode为singleInstance时,总是在新的任务中开启,并且这个新的任务中有且只有这一个实例,也就是说被该实例启动的其他activity会自动运行于另一个任务中。当再次启动该activity的实例时,会重用已存在的任务和实例。并且会调用这个实例的onNewIntent()方法,将Intent实例传递到该实例中。和singleTask相同,同一时刻在系统中只会存在一个这样的Activity实例。 一个Activity的Launch Mode为singleInstance时,与singleTask模式相同的是在新建这个Activity时,会把它放在一个新的stack中并置于顶部(即放在新的task中)。与singleTask模式不同的是,这个新建的task的stack永远只会有一个元素,就是这个Activity自己。如果这个Activity已经在某个Task的stack中了(这个stack必定只有一个元素,那就是这个Activity自己),此时只会调用它的onNewIntent(),而不会调用onCreate()。 因为new这两类activity,都会新建到新task。而且如果启动本task已有singletask类型的activity,他会销毁上面的activity,所以也不会得到返回结果,。综上所述,启动这两类activity不会得到返回&#;,startactivityforresult,会马上执行onresult,得不到数据,会cancle。所以失效。 activityA用startactivityforresult启动ActivityB(singletask),B会放到A上面,俩在同一个task,但是startactivityforresult不会作用,只会马上会 case RESULT_CANCELED: 然后再进入B的onCreate,也不会得到返回&#;,所以这里只能理解是协议规范了记住singletask的activity不要用startactivityforresult就好,但是能启动在一个task,只是无法传&#;。说道协议的关系,那么就会存在一种情况,B已经存在,B下面还有C,那此时finishB,前台出现的C,也是不会返回&#;给A的,介于这种情况存在,activityA用startactivityforresult启动ActivityB(singletask),协议规范马上执行onresult case RESULT_CANCELED:也就能理解了。具体参照博文Sodino。 taskAffinity表示一个任务,这个任务就是当前activity所在的任务。The task that the activity has an affinity for在概念上,具有相同的affinity的activity(即设置了相同taskAffinity属性的activity)属于同一个任务。一个任务的affinity取决于这个任务的根activity(root activity)的taskAffinity。默认情况下,一个应用中的所有activity具有相同的taskAffinity,即应用程序的包名。我们可以通过设置不同的taskAffinity属性给应用中的activity分组,也可以把不同的应用中的activity的taskAffinity设置成相同的&#;。为一个activity的taskAffinity设置一个空字符串,表明这个activity不属于任何task。taskAffinity可以影响当activity以FLAG_ACTIVITY_NEW_TASK标志启动时,它会被启动到哪个任务中。这句话的意思是,当新启动的activity(SecondActivity)是以FLAG_ACTIVITY_NEW_TASK标志启动时(可以认为FLAG_ACTIVITY_NEW_TASK和singleTask作用相同,当启动模式为singleTask时,framework会将它的启动标志设为FLAG_ACTIVITY_NEW_TASK),framework会检索是否已经存在了一个affinity为SecondActivity的taskAffinity.second的任务(即一个TaskRecord对象),而不是随便新建task,有和SecondActivity的taskAffinity时就不新建task了,只是去那个和自己属性一样的task,如果当前的task就是和自己属性相同那就是在当前task了,官方文档可能就是这意思,寻觅和自己属性相同的“新”task。1、如果存在这样的一个任务,则检查在这个任务中是否已经有了一个SecondActivity的实例,如果已经存在一个SecondActivity的实例,重用这个任务和任务中的SecondActivity实例,将这个任务调到前台,清除位于SecondActivity上面的所有Activity,显示SecondActivity,并调用SecondActivity的onNewIntent();如果不存在一个SecondActivity的实例,会在这个任务中创建SecondActivity的实例,并调用onCreate()方法。2、[原]深刻理解activity启动模式,彻底理解android的四种启动模式,尤其singleTask(深入理解)

如果不存在这样的一个任务,会创建一个新的affinity为com.jg.zhang.androidtasktest.second的任务,并且将SecondActivity启动到这个新的任务中。。。SecondActivity只设置启动模式为singleTask,而不设置taskAffinity,即和启动他的Activity的taskAffinity相同,都为应用的包名,那么SecondActivity是不会开启一个新任务的,这就是著名的怪现象(文档表述不清造成)。 framework中的判定过程如下:1、在MainActivity启动SecondActivity时,发现启动模式为singleTask,那么设定他的启动标志为FLAG_ACTIVITY_NEW_TASK。。2、然后获得SecondActivity的taskAffinity,即为包名com.xxx.xxx。3、检查是否已经存在一个affinity为com.xxx.xxx的任务,这个任务是存在的,就是MainActivity所在的任务,这个任务是在启动MainActivity时开启的4、既然已经存在这个任务,就检索在这个任务中是否存在一个SecondActivity的实例,发现不存在5、在这个已有的任务中启动一个SecondActivity的实例。 任务(Task)不还可以跨进程(Process)。把两个singleTask的aty设置成相同的taskAffinity的时候,X app的A aty 启动B aty ,home。Y app的C aty启动D aty时,B和D是一样的taskAffinity,那么B和D会在一个task但是AB一个进程CD一个进程。 设置singleTask模式只意味着“可以在一个新的任务中开启”,至于是不是真的会在新任务中开启,在framework中还有其他条件的限制。由上面的介绍可知,这个条件为:是否已经存在了一个由他的taskAffinity属性指定的任务。 在启动一个singleTask的Activity实例时,如果系统中已经存在这样一个实例,就会将这个实例调度到任务栈的栈顶,并清除它当前所在任务中位于它上面的所有的activity。此时不走oncreate,走onNewIntent()。 以singleInstance模式启动的Activity具有全局唯一性,即整个系统(整个系统所有的app中只有一个)中只会存在一个这样的实例,具有独占性,即它会独自占用一个任务,被他开启的任何activity都会运行在其他任务中,被singleInstance模式的Activity开启的其他activity,能够开启一个新任务,但不一定开启新的任务,也可能在已有的一个任务中开启。 我们在操作软件的过程中,一定会涉及界面的跳转。其实在对界面进行跳转时,Android Framework既能在同一个任务中对Activity进行调度,也能以Task为单位进行整体调度。在启动模式为standard或singleTop时,一般是在同一个任务中对Activity进行调度,而在启动模式为singleTask或singleInstance是,一般会对Task进行整体调度。

onNewIntent()非常好用,Activity第一启动的时候执行onCreate()---->onStart()---->onResume()等后续生命周期函数,也就时说第一次启动Activity并不会执行到onNewIntent(). 而后面如果再有想启动Activity的时候,那就是执行onNewIntent()---->onResart()------>onStart()----->onResume(). 如果android系统由于内存不足把已存在Activity释放掉了,那么再次调用的时候会重新启动Activity即执行onCreate()---->onStart()---->onResume()等。 当调用到onNewIntent(intent)的时候,需要在onNewIntent() 中使用setIntent(intent)赋&#;给Activity的Intent.否则,后续的getIntent()都是得到老的Intent。

Android视图自定义View绘制流程完全解析,带你一步步深入了解View(二) 在上一篇文章中,我带着大家一起剖析了一下LayoutInflater的工作原理,可以算是对View进行深入了解的第一步吧。那么本篇文章中,我们将继续对View进行

更改Android应用程序的图标 对于android应用程序的开发,默认的图标是一个小机器人,图片名称为ic_launcher.png。但是,大多数开发者是会将这个图标在开发过程中改为自己设计的icon

详解onMeasure()方法中如何测量一个控件尺寸

标签: 深入理解

本文链接地址:https://www.jiuchutong.com/biancheng/370947.html 转载请保留说明!

上一篇:Android自定义答题进度条(android 自定义dialog)

下一篇:Android视图自定义View绘制流程完全解析,带你一步步深入了解View(二)(android 自定义view onlayout)

  • 中税协是什么意思
  • 期初未缴税额是什么意思
  • 个人名字的话费能做账吗
  • 投资款可以是现金吗
  • 内涵报酬率和必要投资报酬率
  • 办公室转租怎么给对方开发票
  • 科目汇总表会计核算形式
  • 企业所得税汇算清缴补缴税款分录
  • 跨年主营业务成本直接冲回可以吗
  • 资产一次性摊销
  • 公司团建收取员工费用
  • 增值税发票退票时间
  • 营改增以前建筑税率
  • 旅游服务费计入什么费用
  • 通信服务费计入什么科目
  • 统一信用社会代码怎么填
  • 一般纳税人企业要交哪些税
  • 合同银行账户与开票信息不一致会计如何处理
  • 第二季度的利润表报错了,怎么重新报
  • 无形资产摊销完还需要报废
  • 公司员工补充医疗保险方案
  • 预借差旅费计入其他应收款吗
  • 银行贷款入公账怎么入分录?
  • 进项票未认证怎么入账
  • 福利费需要扣税吗
  • macbookair怎么设置屏幕
  • 在win7系统中将打开窗口拖到屏幕顶端
  • mcshield.exe是什么进程
  • 商业会计做账
  • 二手车交易如何开票
  • thinkphp5.0.23
  • 应付福利费和应付职工薪酬的关系
  • 勃朗峰高度
  • 个人独资企业法律责任
  • 一个简单安全的小故事
  • 超参数设置
  • 新成立的公司怎么算生育津贴
  • 增值税发票抵扣联和发票联
  • 开了专票就不能享受政策
  • 成本核算的会计处理
  • 企业销售旧车如何开票
  • python中的列表和元祖有什么区别
  • dede织梦怎么转成zblog
  • 贴现手续费计入哪个明细科目
  • 增值税发票的认证
  • 设计模式模板方法和策略模式对比
  • 10万销售额是含税还是不含税
  • 其他应付款借方余额怎么调整
  • 本月记账之前是不是要结转上月
  • 企业净利润怎么查询数据
  • 公司购买的商业保险如何使用
  • 物业公司预收的物业费怎么做账
  • 营业外收入是损益类账户吗
  • 加油充值卡开票内容是什么
  • 4s店出售试驾车的增值税是多少
  • 年末待处理财产损益有余额怎么办
  • 懒癌患者如何自救
  • win7系统管理在哪
  • 获取windows的最新信息
  • 快速关机的快捷方式
  • ubuntu听音乐
  • 雨林木风 winxp sp3 安装版 ys8.0
  • pln是什么文件
  • win10怎么用ios上网
  • 批处理 /b
  • js实现分页数据库数据
  • css checked
  • 简易最新版本
  • 如何理解vue
  • nodejs的流处理模块
  • javascript的介绍
  • jquery不生效的原因
  • 成都市电子税务局网上申报
  • 甘肃增值税发票查验平台官网
  • 北京市地方税务局2015第10号文件
  • 安徽增值税普通发票税率1%
  • 东莞房地产协会副会长
  • 深圳献血奖励标准
  • 怎么删除天眼查信息
  • 国家税务总局办公室电话
  • 免责声明:网站部分图片文字素材来源于网络,如有侵权,请及时告知,我们会第一时间删除,谢谢! 邮箱:opceo@qq.com

    鄂ICP备2023003026号

    网站地图: 企业信息 工商信息 财税知识 网络常识 编程技术

    友情链接: 武汉网站建设