位置: 编程技术 - 正文

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

  • 工地工贸药品入库流程
  • 财务刷卡手续费怎么处理
  • 出纳记账购进的货物
  • 经营性现金流量净额是什么意思
  • 本地的住宿费怎么交
  • 投资者回售选择权是什么意思
  • 行政单位会议纪要范文3篇
  • 外贸企业申报出口退税时的会计分录
  • 企业股权转让影响利润吗
  • 车辆购置税完税证明网上打印
  • 技术转让所得的税收优惠
  • 公司接受投资会计科目
  • 制造费用结转后有没有余额
  • 小规模发票跨月冲红怎么做账
  • 员工借款会计科目
  • 申请补贴费用怎么写
  • 日常生活中各种仪式
  • 支付给对方的押金
  • 去年成立的公司今年需要年检吗
  • 增值税 3万
  • 代理报关业务
  • 购买礼品赠送客户进项税处理
  • 不含税单价怎么换成含税单价
  • 国外企业提供国际运输服务税率
  • 应收账款负数可以调到哪个科目
  • 固定资产注资后怎么做账
  • 土地使用权摊销年限最新规定
  • 服务器ssl证书过期怎么解决
  • 会计报表申报期限怎么填
  • 进项税额转出如何做账分录
  • 电脑cpu风扇不动怎么办
  • 第三方检测公司有前途吗
  • PHP:pg_fetch_object()的用法_PostgreSQL函数
  • 非货币性资产交换是企业经常发生的
  • 发票系统技术维护费
  • PyTorch 深度学习实战 |用 TensorFlow 训练神经网络
  • Vue2 Element description组件 列合并
  • 特斯拉 ai day
  • php实现批量删除
  • php连接mysql8.0
  • 发票作废怎么操作电脑上
  • 劳动仲裁要出钱吗
  • 公司多余的钱叫什么
  • java守护线程和普通线程jvm区别
  • mysql中的外键的作用
  • 帝国cms使用手册
  • 农机销售免税政策
  • 国家定额发票使用范围
  • 商誉的会计核算怎么核算
  • 进项税为什么记在贷方
  • 资产负债表编制
  • 销售公司扣款制度合法吗
  • 印花税缴纳时间点
  • 到期无法收回的银行承兑汇票计入什么科目
  • 坏账损失的定义
  • 代扣税是不是社保
  • 出租房屋损坏赔偿
  • 装修费用摊销计入什么科目
  • 做账一定要计提本月工资吗
  • 税务开票系统如何设置不用重复登录
  • 银行存款日记账怎么记账
  • sqlserver存储过程怎么查看
  • windows取消ctrl+alt+del
  • Win10 Mobile 10572预览版新增了哪些功能? 更新内容汇总
  • ubuntu安装指南
  • linux whoami命令详解
  • cocos-creator
  • 实例的英文
  • 移动端网页开发技术
  • eval()函数python
  • codeblocks使用技巧
  • dos命令查看
  • 深入浅出python
  • andriod 控件
  • jQuery中bind(),live(),delegate(),on()绑定事件方法实例详解
  • 王军调研地税局的职务
  • 开票软件提示连接服务器失败怎么办
  • 长沙个体户缴纳个税
  • 个人开具农产品普通发票
  • 省纪检委派驻机构值得去么
  • 免责声明:网站部分图片文字素材来源于网络,如有侵权,请及时告知,我们会第一时间删除,谢谢! 邮箱:opceo@qq.com

    鄂ICP备2023003026号

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

    友情链接: 武汉网站建设