位置: 编程技术 - 正文

[原]深刻理解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)

  • 企业所得税的计提和缴纳分录
  • 所得税费用怎么算分录
  • 个人分红怎么算
  • 小规模普通发票要交税吗
  • 股权变更后税务需要变更吗
  • 哪些企业适用于品种法
  • 处置使用过的车辆
  • 季度的工会经费计税依据
  • 税收分类编码不可用是什么原因
  • 国际多式联运必须具备的基本条件是什么
  • 赠送车子需要过户吗
  • 销售折扣怎么开
  • 货运代理公司会计涉及的科目
  • 公司债权转让如何处理
  • 由于疏忽装修费用之前没有摊销应如何处理
  • 产品质量问题怎么处罚
  • 出口退税进项税额转出是什么意思
  • 部分销售退回怎么开票
  • 哪家银行存款利率高2023
  • 自然人增值税免税额
  • 申报文件解密失败怎么办?
  • 其他应收款无法收回的会计分录
  • 应收代位偿款
  • 无票收入后附什么凭证
  • 股利如何算
  • 企业利息收入如何做分录
  • 生物资产全套账务处理
  • 建筑安装服务费可以抵扣进项税吗
  • 会计帐务处理程序
  • 华为手机屏幕变成黑白色怎么恢复
  • 发票金额大于报销金额可以吗
  • 工资里的其他应收款是什么
  • php文件流
  • PHP:imagepsloadfont()的用法_GD库图像处理函数
  • 以前年度企业所得税分录
  • 高翔ORB-SLAM2稠密建图编译(添加实时彩色点云地图+保存点云地图)
  • 成本法处置子公司丧控合并层面
  • php转utf8
  • 成本费用损失的区别和联系
  • 查询命令的操作步骤
  • 材料盘盈分录
  • 公司请的临时工
  • phpcms v9安装教程
  • 企业研发费用可以抵税吗
  • 增值税主表和附表
  • sql 封装
  • sql server 性能优化
  • mongodb添加数据库
  • 盈余公积的会计科目
  • 企业计提坏账准备时应该借记什么科目
  • 小微企业季度收入
  • 广告费和业务宣传费
  • 母公司代子公司收款,子公司开具发票
  • 预存返现活动规则
  • 飞机票没有发票只有行程单
  • 企业清算期间发生的各项费用应计入以下什么科目
  • 合理损耗怎么算
  • 固定资产折旧的会计科目
  • 公司注销其他应收款余额要交税吗
  • 客观原因怎么写
  • sqlserver 断开数据库连接
  • sqlserver响应好慢
  • Windows系统sid修改方法
  • 如何去掉macbook开机密码
  • bios设置USB启动英文
  • bios界面如何进入
  • wcu.exe是什么
  • WIN10系统中没有接入音频设备 要启动gui
  • shell检查语法错误
  • linux修改环境变量后需要重启吗
  • jquery实现仿新浪微博带动画效果弹出层代码(可关闭、可拖动)
  • 网站备份工具
  • 批处理for /f
  • Python中强大的命令行库click入门教程
  • c#string stringbuilder
  • 安卓多点触屏在哪里设置
  • 落实落地是什么意思
  • 国税局下设几个部门
  • 青霉素过敏是因为提纯不好吗
  • 企业注册的步骤
  • 免责声明:网站部分图片文字素材来源于网络,如有侵权,请及时告知,我们会第一时间删除,谢谢! 邮箱:opceo@qq.com

    鄂ICP备2023003026号

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

    友情链接: 武汉网站建设