橱柜手机网站模板,微信小程序官网,dw在线编辑器,成品网站货源入口目录Activity生命周期任务栈启动模式Intent FlagtaskAffinity属性1.Activityactivity的简单介绍就不写了#xff0c;作为最常用的四大组件之一#xff0c;肯定都很熟悉其基本用法了。2.生命周期首先#xff0c;是都很熟悉的一张图#xff0c;即官方介绍的Activity生命周期图…目录Activity生命周期任务栈启动模式Intent FlagtaskAffinity属性1.Activityactivity的简单介绍就不写了作为最常用的四大组件之一肯定都很熟悉其基本用法了。2.生命周期首先是都很熟悉的一张图即官方介绍的Activity生命周期图.Activity生命周期图情景打开某个应用的的FirstActivity调用方法如下由于之前已经很熟悉了这里就简单贴一些图。Paste_Image.png按下返回键Paste_Image.png重新打开并按下home键Paste_Image.png再重新打开Paste_Image.png在其中打开一个DialogActivity(SecondActivity)Paste_Image.png按下返回Paste_Image.png修改SecondAcitvity为普通Activity,依旧是上述操作:Paste_Image.png这里强调一下onSaveInstanceState(Bundle outState)方法的调用时机当Activity有可能被系统杀掉时调用注意一定是被系统杀掉自己调用finish是不行的。测试如下FirstActivity启动SecondActivityPaste_Image.png如果SecondActivity是android:themeandroid:style/Theme.Dialog那么Paste_Image.png如果FirstActivity启动SecondActivity后自己调用了finish方法Paste_Image.png也就是说只要一个Activity转为后台那么就会调用此方法因为其有可能被系统杀掉其中存的Bundle对象就是用来存储数据的这个也就是onCreate方法中Bundle对象参数savedInstanceState的由来。3.Acitvity任务栈一个App会包含很多个Activity多个Activity之间通过intent进行跳转那么原始的Activity就是使用栈这个数据结构来保存的。TaskA task is a collection of activities that users interact with when performing a certain job. The activities are arranged in a stack (theback stack), in the order in which each activity is opened.即若干个Activity的集合的栈表示一个Task。当App启动时如果不存在当前App的任务栈就会自动创建一个默认情况下一个App中的所有Activity都是放在一个Task中的但是如果指定了特殊的启动模式那么就会出现同一个App的Activity出现在不同的任务栈中的情况即会有任务栈中包含来自于不同App的Activity。4.启动模式standard标准模式在不指定启动模式的情况下都是以此种方式启动的。每次启动都会创建一个新的Activity实例覆盖在原有的Activity上原有的Activity入栈。测试如下在FirstActivity中启动FirstActivity:Paste_Image.png当只有一个FirstActivity时堆栈情况Paste_Image.png当在FirstActivity中启动FirstActivity时堆栈情况Paste_Image.png这就很显然了任务栈中一共有两个FirstActivity即表示每次启动FirstActivity都是创建了一个新的实例。singleTop此种模式下Activity在启动时会进行判断如果当前的App的栈顶的Activity即正在活动的Activity就是将要启动的Activity那么就不会创建新的实例直接使用栈顶的实例。测试设置FirstActivity为此启动模式多次点击FirstActivity中的启动FirstActivity的按钮查看堆栈情况(其实点击按钮没有启动新Activity的动画就可以看出并没有启动新Activity)Paste_Image.png果然堆栈中只有一个FirstActivity如果我在FirstActivity中启动了SecondActivity此时FirstActivity不就不在栈顶了么此时我再启动FirstActivity会怎样呢测试如下Paste_Image.png很好的验证了只有在栈顶时才不会创建新实例。这种启动模式很适用于接收到消息之后进行显示的界面总不能每次来消息都创建新实例那一次来个十几条消息岂不是爆炸了。在此种模式下在不创建新的实例的时候会调用onNewIntent()方法。总结栈顶的Activity只会有一个实例在栈顶的情况下重复启动该Activity只会复用该Activity,而不会创建一个新的除了栈顶的Activity外其他的和standard类似每次启动都会被创建一个新的实例。onNewIntent(Intent intent)方法介绍官方解释如下This is called for activities that set launchMode to singleTop in* their package, or if a client used the {link Intent#FLAG_ACTIVITY_SINGLE_TOP}* flag when calling {link #startActivity}. In either case, when the* activity is re-launched while at the top of the activity stack instead* of a new instance of the activity being started, onNewIntent() will be* called on the existing instance with the Intent that was used to* re-launch it.** An activity will always be paused before receiving a new intent, so* you can count on {link #onResume} being called after this method.** Note that {link #getIntent} still returns the original Intent. You* can use {link #setIntent} to update it to this new Intent.** param intent The new intent that was started for the activity.大意就是对于使用singleTop启动或Intent.FLAG_ACTIVITY_SINGLE_TOP启动的Activity当该Activity被重复启动(注意一定是re-launched第一次启动时不会调用)时就会调用此方法。且调用此方法之前会先暂停Activity也就是先调用onPause方法。而且即使是在新的调用产生后此方法被调用但是通过getIntent方法获取到的依旧是以前的Intent可以通过setIntent方法设置新的Intent。方法参数就是新传递的Intent.singleTask1.如果是同一个App中启动某个设置了此模式的Activity的话如果栈中已经存在该Activity的实例那么就会将该Activity上面的Activity清空并将此实例放在栈顶。测试SecondActivity启动模式设为singleTask启动三个ActivityPaste_Image.png然后在ThirdActivity中启动SecondActivity(注意不是返回而是启动):Paste_Image.png果然SecondActivity上的ThirdActivity被清掉了2.如果是其他应用的Activity启动的本应用中此Activity那么- 本应用未启动时在另一个应用的ActivityY中启动SecondActivityPaste_Image.png显然此时这个SecondActivity是在一个单独的任务栈中的且是处于前台的按下返回键SecondActivity结束返回到ActivityY。- 本应用已经启动了在后台运行任务栈中是FirstActivity和SecondActivity在另一个应用的ActivityY中启动此Activity此时任务栈的状态Paste_Image.png两个任务栈每个栈中都有两个Activity。注意此时如果按下返回键会出现什么情况呢到底是返回到ActivityY还是返回到FirstActivity结果如下Paste_Image.png前台Activity竟然变成了FirstActivity继续按下返回键就会返回到ActivityYActivityX然后退出。也就是说在ActivityY启动了SecondActivity时连带着SecondActivity的任务栈也被带到了前台。那么我不禁要问了如果SecondActivity启动模式是默认的会不会是此种情况呢其实按照我们前面学的按照分析的话应该是SecondActivity在ActivityY所在的App所对应的任务栈中创建一个新的实例跟原本的SecondActivity所在后台任务栈没有一毛钱关系。- 本应用已经启动了三个Activity任务栈中是FirstActivity和SecondActivity和ThirdActivity此时再由ActivityY启动那么稍微思考一下就可以肯定运行结果跟上面是完全相同的因为在跳转到SecondActivity时其上面的Activity已经被清空了。singleInstance这个模式就很好记以此模式启动的Activity会存放在一个单独的任务栈中且只会有一个实例。测试SecondActivity启动模式设为singleInstanceFirstActivity-SesondActivity-ThirdActivity-SecondActivity-ThirdActivity结果Paste_Image.png显然启动了两次ThirdActivity任务栈中就有两个实例而SecondActivity在另外一个任务栈中且只有一个。5.Intent Flag设置启动模式在使用Intent启动一个Activity时可以设置启动该Activity的启动模式这个属性有很多大致列出几个Intent.FLAG_ACTIVITY_NEW_TASK每个启动的Activity都在一个新的任务栈中Intent.FLAG_ACTIVITY_SINGLE_TOPsingleTopIntent.FLAG_ACTIVITY_CLEAR_TOPsingleTaskIntent.FLAG_ACTIVITY_NO_HISTORY用此种方式启动的Activity在它启动了其他Activity后会自动finish.6.taskAffinity属性官方文档介绍如下The task that the activity has an affinity for. Activities with the same affinity conceptually belong to the same task (to the same application from the users perspective). The affinity of a task is determined by the affinity of its root activity.The affinity determines two things — the task that the activity is re-parented to and the task that will house the activity when it is launched with the FLAG_ACTIVITY_NEW_TASK flag.By default, all activities in an application have the same affinity. You can set this attribute to group them differently, and even place activities defined in different applications within the same task. To specify that the activity does not have an affinity for any task, set it to an empty string.If this attribute is not set, the activity inherits the affinity set for the application (see theelements taskAffinity.The name of the default affinity for an application is the package name set by theelement.大意如下这个属性表示的是一个Activity对任务栈的亲和度。有相同的affinity的Activity属于同一个Task即affinity相同的Activity会被加入同一任务栈。一个任务栈的affinity由其affinity值确定或是其根Activity的affinity确定。这个属性决定两件事①Activity被re-parented时的任务栈②以FLAG_ACTIVITY_NEW_TASK启动的Activity所在的任务栈。默认情况下同一个应用内的所有的Activity都拥有相同的affinity你可以通过设置这个值来给Activity分组甚至将不同应用的Activity放在相同的任务栈中。为了表明一个Activity对任何一个任务栈都不具有亲和力那么将其设为空字符串。如果这个值没有设置那么就默认使用application标签下的这个值。默认的affinity值为manifest标签下设置的包名。这样看来的话通俗易懂的讲就是给每一个任务栈起个名给每个Activity也起个名在Activity以singleTask模式启动时就检查有没有跟此Activity的名相同的任务栈有的话就将其加入其中。没有的话就按照这个Activity的名创建一个任务栈。测试在App1中设置SecondActivity的taskAffinity为“gsq.test”App2中的ActivityX的taskAffinity也设为“gsq.test”FirstActivity-SesondActivity-home-ActivityX任务栈信息如下Paste_Image.png结果很显然了。测试在上述基础上在ActivityX中进行跳转到ActivityY,ActivityY不指定启动模式和taskAffinity。结果如下Paste_Image.png发现ActivityY在gsq.test任务栈中这是由于其启动模式是Standard也就是在启动这个Activity的所在的任务任务栈中。再将ActivityY指定启动模式singleTaskPaste_Image.png这样就没问题了ActivityY在一个新的任务栈中名称为包名。这时从ActivityY跳转到SecondActivity那应该是gsq.test任务栈只有SecondActivityActivityX已经没有了。因为其启动模式是singleTask在启动它时发现已经有一个实例存在就把它所在的任务栈上面的Activity都清空了并将其置于栈顶。还有一点需要提一下在上面FirstActivity是App1的lunch Activity但是由于SecondActivity并没有指定MAIN和LAUNCHER过滤器故在FirstActivity跳转到SecondActivity时按下home键再点开App1回到的是FirstActivity。大致就先写这么多吧好像有点长废话有点多估计也有错别字不要太在意~~~