activity启动模式,Android中的Activity详解--启动模式与任务栈
activity启动模式,Android中的Activity详解--启动模式与任务栈详细介绍
本文目录一览: android 怎么设置activity的启动模式
android 怎么获取一个activity启动模式 在Android中每个界面都是一个Activity,切换界面操作其实是多个不同Activity之间的实例化操作。在Android中Activity的启动模式决定了Activity的启动运行方式。 Android总Activity的启动模式分为四种: Activity启动模式设置:
Activity的四种启动模式: 1. standard 模式启动模式,每次激活Activity时都会创建Activity,并放入任务栈中。 2. singleTop 如果在任务的栈顶正好存在该Activity的实例, 就重用该实例,否者就会创建新的实例并放入栈顶(即使栈中已经存在该Activity实例,只要不在栈顶,都会创建实例)。 3. singleTask 如果在栈中已经有该Activity的实例,就重用该实例(会调用实例的onNewIntent())。重用时,会让该实例回到栈顶,因此在它上面的实例将会被移除栈。如果栈中不存在该实例,将会创建新的实例放入栈中。 4. singleInstance 在一个新栈中创建该Activity实例,并让多个应用共享改栈中的该Activity实例。一旦改模式的Activity的实例存在于某个栈中,任何应用再激活改Activity时都会重用该栈中的实例,其效果相当于多个应用程序共享一个应用,不管谁激活该Activity都会进入同一个应用中。 其中standard是系统默认的启动模式。
下面通过实例来演示standard的运行机制: 1 private TextView text_show; 2 private Button btn_mode; 3 4 @Override 5 public void onCreate(Bundle savedInstanceState) { 6 super.onCreate(savedInstanceState); 7 setContentView(R.layout.activity_main); 8 9 text_show = (TextView) this.findViewById(R.id.text_show); 10 11 text_show.setText(this.toString()); 12 13 btn_mode = (Button) this.findViewById(R.id.btn_mode); 14 15 } 16 按钮单击事件 17 public void LaunchStandard(View v){ 18 startActivity(new Intent(this,MainActivity.class)); 19 20 text_show.setText(this.toString()); 21 }
如何设置Activity的启动模式
Activity的四种启动模式:standard:这是默认模式,每次激活Activity时都会创建Activity实例,并放入任务栈中。 singleTop: 如果在任务的栈顶正好存在该Activity的实例,就重用该实例( 会调用实例的 onNewIntent() ),否则就会创建新的实例并放...
android 主activity用什么启动模式 在android里,有4种activity的启动模式,分别为: “standard” (默认) “singleTop” “singleTask” “singleInstance” 1. 如何决定所属task “standard”和”singleTop”的activity的目标task,和收到的Intent的发送者在同一个task内,除非intent包括参数FLAG_ACTIVITY_NEW_TASK。 如果提供了FLAG_ACTIVITY_NEW_TASK参数,会启动到别的task里。 2. 是否允许多个实例 “standard”和”singleTop”可以被实例化多次,并且存在于不同的task中,且一个task可以包括一个activity的多个实例; “singleTask”和”singleInstance”则限制只生成一个实例,并且是task的根元素。 singleTop要求如果创建intent的时候栈顶已经有要创建 的Activity的实例,则将intent发送给该实例,而不发送给新的实例。 3. 是否允许其它activity存在于本task内 “singleInstance”独占一个task,其它activity不能存在那个task里;如果它启动了一个新的activity,不管新的activity的launch mode 如何,新的activity都将会到别的task里运行(如同加了FLAG_ACTIVITY_NEW_TASK参数)。 而另外三种模式,则可以和其它activity共存。 4. 是否每次都生成新实例 “standard”对于没一个启动Intent都会生成一个activity的新实例; “singleTop”的activity如果在task的栈顶的话,则不生成新的该activity的实例,直接使用栈顶的实例,否则,生成该activity的实例。 比如现在task栈元素为A-B-C-D(D在栈顶),这时候给D发一个启动intent,如果D是 “standard”的,则生成D的一个新实例,栈变为A-B-C-D-D。 如果D是singleTop的话,则不会生产D的新实例,栈状态仍为A-B-C-D 如果这时候给B发Intent的话,不管B的launchmode是”standard” 还是 “singleTop” ,都会生成B的新实例,栈状态变为A-B-C-D-B。
“singleInstance”是其所在栈的唯一activity,它会每次都被重用。
“singleTask”如果在栈顶,则接受intent,否则,该intent会被丢弃,但是该task仍会回到前台。
当已经存在的activity实例处理新的intent时候,会调用onNewIntent()方法 如果收到intent生成一个activity实例,那么用户可以通过back键回到上一个状态;如果是已经存在的一个activity来处理这个intent的话,用户不能通过按back键返回到这之前的状态。 总结如下: standard 每次都会新建,每个Task都可以有,且每个Task都可以有多个实例(每个Task都可以有,且可以有多个) singleTop 当前实例如果在栈顶,就不新建实例,调用其OnNewIntent。 如不在栈顶,则新建实例 (每个Task都可以有,且可以有多个,在栈顶时可复用) singleTask 新建一个Task,如果已经有其他的Task并且包含该实例,那就直接调用那个Task的实例。(只有一个Task中会有) singleInstance 新建一个Task,且在该Task中只有它的唯一一个实例。 (只有一个Task会有,且该Task中只有它) FLAG_ACTIVITY_NEW_TASK 类似singleTask FLAG_ACTIVITY_SINGLE_TOP 类似singleTop FLAG_ACTIVITY_CLEAR_TOP 无对应
Android开发,activity的默认启动模式为标准启动模式,什么时候会用到其他的启动模式? 启动模式简单地说就是Activity启动时的策略,在AndroidManifest.xml中的标签的android:launchMode属性设置; 启动模式有4种,分别为standard、singleTop、singleTask、singleInstance; 讲解启动模式之前,有必要先了解一下“任务栈”的概念; 一 : standard 模式:这个就没有什么好说的了,Android默认Activity启动的模式 就是 standard,如果有3个 Activity,Act1,Act2,Act3, 如果从Act1 启动到Act2 ,在启动到Act3,那么Android 的任务栈(task stack)分别为 Act1、Act2、Act3,Act3 在栈顶,如果此时按手机返回键,则需要返回3次才能返回到桌面(假设是从桌面启动的demo),任务栈分销毁掉 Act3,Act2,最后Act1 。 二 :singleTop模式: 实验效果: singleTop模式:该启动模式和standard模式相差不多,任务栈分配也很相似,如:现有 act1,act 2,在act2 清单文件中配置 android:launchMode="singleTop" ,其他都是默认standard 模式, 若从桌面启动该实验demo,从act 1,到act2 ,那么任务栈则分配为,act1,act2,此时该任务栈和 standard 模式任务栈分配则完全相同,接下来则说明不同的地方,如果在act2 界面中 启动 到act1, 此时的 任务栈 情况则为 act1,act2,act1,在由act1 启动到act2,在启动到act2,进行多次启动,(在act2界面)任务栈的情况则为,act1,act2,act1,act2,栈顶的act2 则不会重新创建,则会复用act2 该 Activit, 依次类推。 理论知识: singleTop,如果任务栈的栈顶元素是要被激活的组件,不会创建新的Activity放在任务栈,而是会复用栈顶的Activity。 如果发现栈顶的元素不是要激活的Activity,就会创建新的Activity 放置到任务栈里面 singleTop模式应用场景 : App程序中(或浏览器中)保存的书签,假如用户看到一个界面保存自己喜欢的标签,假如要保存10个,这个时候用户在返回键的时候,则会返回10次才能返回到App应用中, Android下singleTop 则解决该问题。 三 singleTask 模式 : 实验效果 相差不大,实验内容就不多说了,自己可以写个小demo,两个Activity,每个Activiy 有两个button,可以相互启动 打日志去动手查看,会理解更加深刻,可以参照着 SingleTop模式去实验,以下只是讲解下 和SingleTop的区别: 区别如下:(理论知识) SingleTask 操作模式,一般和singleTop操作模式类似,如果他发现任务栈里面已经有了要启动的这个Activity,他会清空这个Activity所在的任务栈上面的所有Activiy,然后直接复用这个已经存在的Activity 。 应用场景: 如果一个App中,有一个功能需要加载网页内容 ,打开一个 browserActiviy现在网页内容,则内存开销非常大,首先要初始化webkit /c++ 嵌入式浏览器内核broweractivity 配置了singleTask,空间换时间,使用该模式可以节省内存开销。 四 :singleinstance 模式 : 直接理论知识吧”: singleInstance操作模式会新开启一个任务栈,跟其他普通Activity不是 同一个任务栈,比较牛,他的模式流程是 首先要新开启一个新的任务栈把要激活的Activity放置到新的 任务栈里,这个任务栈里面只有且 只有一个实例,也比较极端吧。说比较极端也跟他的应用场景有关系。 应用场景 : App各种词典,向有道词典,什么金山词典,说极端是因为不想被放置到同一个任务栈里面,它是全局的系统程序应用,达到节省内存的使用目的。
win7 系统 怎么设置uefi启动模式 存有ghost版win7系统iso镜像文件的u启动uefi u盘启动盘插在电脑u *** 接口上,然后重启电脑,在出现开机画面时用一键u盘启动快捷键的方法进入到启动项选择窗口,然后将光标移至UEFI:开头的项(注意:一定要选择该项),按回车键执行等待进入到u启动win pe系统,u启动装机工具会自动开启,并加载到u启动uefi u盘启动盘中准备的win7系统安装程序,点击选择c盘为系统安装盘,再点击“确定”按钮继续 随即会弹出一个询问是否执行该操作的提示窗口,点击“确定”按钮执行操作 然后耐心等待win7系统释放完成并自动重启电脑即可 电脑重启后会完成系统后续程序安装应用,直到进入win7系统桌面即可
android开发 activity启动模式中singleTop的疑问 楼主的这一段理论似乎有点不太准确 “在D完成操作以后,我启动了系统内置的浏览器E,根据sdk的说法,浏览器E被放进了一个新任务。那么现在有两个任务” 你凭什么确定浏览器E被放进了一个新的Task呢? 在启动浏览器E的Intent里设置了flag? intentandroid开发 activity启动模式中singleTop的疑问
android-Android activity 的启动模式.新人提问,大侠在哪 Activity的四种启动模式:standard:这是默认模式,每次激活Activity时都会创建Activity实例,并放入任务栈中。 singleTop: 如果在任务的栈顶正好存在该Activity的实例,就重用该实例( 会调用实例的 onNewIntent() ),否则就会创建新的实例并放入栈顶,即使栈中已经存在该Activity的实例,只要不在栈顶,都会创建新的实例。 singleTask:如果在栈中已经有该Activity的实例,就重用该实例(会调用实例的 onNewIntent() )。重用时,会让该实例回到栈顶,因此在它上面的实例将会被移出栈。如果栈中不存在该实例,将会创建新的实例放入栈中。 singleInstance:在一个新栈中创建该Activity的实例,并让多个应用共享该栈中的该Activity实例。一旦该模式的Activity实例已经存在于某个栈中,任何应用再激活该Activity时都会重用该栈中的实例( 会调用实例的 onNewIntent() )。其效果相当于多个应用共享一个应用,不管谁激活该 Activity 都会进入同一个应用中。 位置在 AndroidManifest.xml 文件中 Activity 元素的 android:launchMode 属性。 不知道你要问什么,为你解答
activity的启动模式有哪些 Activity的四种启动模式:standard:这是默认模式,每次激活Activity时都会创建Activity实例,并放入任务栈中。 singleTop: 如果在任务的栈顶正好存在该Activity的实例,就重用该实例( 会调用实例的 onNewIntent() ),否则就会创建新的实例并放入栈顶,即使栈中已经存在该Activity的实例,只要不在栈顶,都会创建新的实例。 singleTask:如果在栈中已经有该Activity的实例,就重用该实例(会调用实例的 onNewIntent() )。重用时,会让该实例回到栈顶,因此在它上面的实例将会被移出栈。如果栈中不存在该实例,将会创建新的实例放入栈中。 singleInstance:在一个新栈中创建该Activity的实例,并让多个应用共享该栈中的该Activity实例。一旦该模式的Activity实例已经存在于某个栈中,任何应用再激活该Activity时都会重用该栈中的实例( 会调用实例的 onNewIntent() )。其效果相当于多个应用共享一个应用,不管谁激活该 Activity 都会进入同一个应用中。 位置在 AndroidManifest.xml 文件中 Activity 元素的 android:launchMode 属性。
Activity的四种启动模式
1、standard:该启动模式为Android默认启动模式,每当启动一个activity就会在任务栈中创建一个? activity,这种模式是默认的,非常浪费空间,但是可以有效的保存之前启动的activity。用于保证之前页面不丢失的时候使用。
?2、single Top:该启动模式是在查看任务栈顶和你将要启动的activity是否是一个activity,是一个就直接复用,否则就新创一个实例,这个经常用于类似聊天界面,当有人给你发消息时更新activity。
3、single Task:该启动模式是在任务栈中看是否有和你一样的activity,有则直接将该activity之上的activity全部弹出使之置于栈顶。常用于一个程序的入口处activity或homeActivity。
4、single Instance:该启动模式是再创建一个任务栈把activity放进去。此模式用于不同应用调用一个activity时应用。用于程序和界面分开的时候。
Android —— Activity的四种启动模式
除了Activity的生命周期外,Activity的启动模式也是一个难点,有时候为了满足项目的特殊需求,就必须使用Activity的启动模式。
在默认情况下,当我们多次启动同一个Activity的时候,系统会创建多个实例并把它们放入任务栈中,但是有些场景重复创建多个实例,是没有必要且浪费资源的,这就需要启动模式来修改系统的默认行为。
下面,我将以理论+实践的形式为大家介绍Activity的启动模式。
这是系统的默认启动模式,采用这种模式的Activity无论是否已经存在实例,都会重新创建一个实例,在这种模式下谁启动了这个Activity,那么这个Activity就运行在启动它的那个Activity所在的栈中。
实践:MainActivity 采用 standard 模式
在这种模式下,如果新的Activity已经位于任务栈的栈顶,那么此Activity不会被重新创建,同时它的 NewIntent 方法将会被回调。如果新Activity的实例已存在但不是位于栈顶,那么新Activity依然会被创建。
实践:MainActivity 采用 singleTop 模式
MainActivity 采用 singleTop 模式,SecondActivity采用 standard 模式
这是一种单实例模式,在这种模式下,只要Activity在一个栈中存在,那么多次启动此Activity都不会重新创建实例,而是回调 onNewIntent() 。
实践:MainActivity 采用 singleTask 模式
MainActivity 采用 singleTask 模式,SecondActivity采用 standard 模式
这是一种加强的 singleTask 模式,它除了具有 singleTask 模式的所有特性外,还加强了一点,那就是具有此模式的Activity只能单独的位于一个任务栈中。
实践:MainActivity 采用 singleInstance 模式
MainActivity 采用 singleInstance 模式,SecondActivity采用 standard 模式
以上就是Activity启动模式的介绍。
欢迎留言指出错误。
Android Activity启动模式与状态保存及恢复详解
???????Activity是 Android组件 中最基本也是最为常见用的四大组件(Activity,Service服务,Content Provider内容提供者,BroadcastReceiver广播接收器)之一 。 ???????Activity是一个应用程序 组件 ,提供一个 屏幕 ,用户可以用来交互为了完成某项任务。 ???????Activity中所有操作都与用户密切相关,是一个负责与 用户交互 的组件,可以通过setContentView(View)来 显示指定控件 。 ???????在一个android应用中,一个Activity通常就是一个单独的屏幕,它上面可以显示一些控件也可以监听并处理用户的事件做出响应。Activity之间通过Intent进行通信。 ???????关于Activity启动流程请参考之前的文章 Android activity启动流程分析
???????activity有四种启动模式,分别为standard,singleTop,singleTask,singleInstance。如果要使用这四种启动模式,必须在manifest文件中
标签中的launchMode属性中配置。
???????标准的默认启动模式,这种模式下activity可以被多次实例化,即在一个task中可以存在多个activity,每一个activity会处理一个intent对象,(在A中再次启动A,会存在后面的A在前面的A上面,当前task会存在两个activity的实例对象)
???????如果一个singleTop模式启动的activity实例已经存在于栈顶,那么再次启动这个activity的时候,不会重新创建实例,而是重用位于栈顶的那个实例,并且会调用实例的onNewIntent()方法将Intent对象传递到这个实例中,如果实例不位于栈顶,会创建新的实例。
???????启动模式设置为singleTask,framework在启动该activity时只会把它标示为可在一个新任务中启动,至于是否在一个新任务中启动,还要受其他条件的限制,即taskAffinity属性。 ??????? taskAffinity :默认情况下,一个应用中的所有activity具有相同的taskAffinity,即应用程序的包名。我们可以通过设置不同的taskAffinity属性给应用中的activity分组,也可以把不同的应用中的activity的taskAffinity设置成相同的值,当两个不同应用中的activity设置成相同的taskAffinity时,则两个activity会属于同一个TaskRecord。 ???????在启动一个singleTask的Activity实例时,如果系统中已经存在这样一个实例,就会将这个实例调度到任务栈的栈顶,并清除它当前所在任务中位于它上面的所有的activity;如果这个已存在的任务中不存在一个要启动的Activity的实例,则在这个任务的顶端启动一个实例;若这个任务不存在,则会启动一个新的任务,在这个新的任务中启动这个singleTask模式的Activity的一个实例。
???????以singleInstance模式启动的Activity具有全局唯一性,即整个系统中只会存在一个这样的实例,如果在启动这样的Activiyt时,已经存在了一个实例,那么会把它所在的任务调度到前台,重用这个实例。 ???????以singleInstance模式启动的Activity具有独占性,即它会独自占用一个任务,被他开启的任何activity都会运行在其他任务中(官方文档上的描述为,singleInstance模式的Activity不允许其他Activity和它共存在一个任务中)。 ???????被singleInstance模式的Activity开启的其他activity,能够开启一个新任务,但不一定开启新的任务,也可能在已有的一个任务中开启,受条件的限制,这个条件是:当前系统中是不是已经有了一个activity B的taskAffinity属性指定的任务。
???????涉及到Activity启动,就不得不说一下Activity的管理,Activity是以什么方式及被什么类来进行管理的,涉及的类主要如下:
???????历史栈中的一个条目,代表一个activity。ActivityRecord中的成员变量task表示其所在的TaskRecord,ActivityRecord与TaskRecord建立了联系。
???????内部维护一个 ArrayList
用来保存ActivityRecord,TaskRecord中的mStack表示其所在的ActivityStack,TaskRecord与ActivityStack建立了联系。
???????内部维护了一个 ArrayList
,用来管理TaskRecord,ActivityStack中持有ActivityStackSupervisor对象,由ActivityStackSupervisor创建。
???????负责所有ActivityStack的管理。内部管理了mHomeStack、mFocusedStack和mLastFocusedStack三个Activity栈。其中,mHomeStack管理的是Launcher相关的Activity栈;mFocusedStack管理的是当前显示在前台Activity的Activity栈;mLastFocusedStack管理的是上一次显示在前台Activity的Activity栈。
???????ActivityThread 运行在UI线程(主线程),App的真正入口。
???????用来实现AMS和ActivityThread之间的交互。
???????负责调用Activity和Application生命周期。
???????当一个Activity未被主动关闭,即“被动关闭”时,可能需要系统给用户提供保持一些状态的入口。
???????前面说的入口就是:Activity提供了onSaveInstanceState()方法,该方法是Activity在关闭前保存状态的核心方法。
???????前面提到“被动关闭”,如果是主动关闭那么就不会调用,比如:按back键、调用finish()等,那么"被动关闭"的场景有哪些呢?下面给列举一下:
???????肯定在调用onStop()前被调用,但不保证在onPause()前 / 后,一般是在onPause()后调用。
???????当需要保持状态时,在onSaveInstanceState()内执行以下逻辑:
???????当需要恢复时,在onCreate()内部执行以下逻辑:
???????布局每个View默认实现:onSaveInstanceState(),即UI的任何改变都会自动的存储和在activity重新创建的时候自动的恢复(只有在为该UI提供了唯一ID后才起作用); ???????若需复写该方法从而存储额外的状态信息时,应先调用父类的onSaveInstanceState()(因为默认的onSaveInstanceState()帮助UI存储它的状态); ???????只使用该方法记录Activity的瞬间状态(UI的状态),而不是去存储持久化数据,因为onSaveInstanceState()调用时机不确定性;可使用 onPause()[一定会执行]存储持久化数据;
???????Activity提供了onRestoreInstanceState()方法,该方法是Activity在重新创建后恢复之前保存状态的核心方法。
???????若被动关闭了Activity,即调用了onSaveInstanceState(),那么下次启动时会调用onRestoreInstanceState()。
???????onCreate()--->onStart()--->onRestoreInstanceState()--->onResume()
??????? 注意: onSaveInstanceState()、onRestoreInstanceState()不一定 成对被调用 ???????如:当正在显示Activity A时,用户按下HOME键回到主界面,然后用户紧接着又返回到Activity A,此时Activity A一般不会因为内存的原因被系统销毁,故Activity A的onRestoreInstanceState()不会被执行; ???????针对以上情况,onSaveInstanceState保持的参数可以选择在onCreate()内部进行解析使用,因为onSaveInstanceState的bundle参数会传递到onCreate方法中,可选择在onCreate()中做数据还原。 ??????? 至此:Activity的启动模式及Activity的状态保持及恢复介绍完毕。
当一个新的activity启动时不会调用以下哪个方法
不会调用goToActivity
android任务栈:我们每次打开一个新的Activity或者退出当前Activity都会在一个称为任务栈的结构中添加或者减少一个Activity组件,一个任务栈包含了一个activity的集合。android通过ActivityRecord、TaskRecord、ActivityStack、ActivityStackSupervisor,ProcessRecord有序地管理每个activity。
一:Standard 标准模式
这是android的默认启动方式,即使不在AndroidManifest.xml里面设置launchMode,也是默认的这个模式。每次启动一个A activity都会创建一个A activity的实例入栈,无论A activity是否存在。
生命周期:onCreate;onStart;onResume都会被调用。
举个例子:任务栈中有A、B、C三个activity,此时C处于栈顶,C的启动模式为Standard。若C跳转到 C;结果还会有一个C activity进入栈中,成为栈顶。
二:SingleTop栈顶复用模式
此模式分为2中情况:(1)如果需要创建的activity已经位于栈顶,此时直接复用该栈顶activity,不再创建新的activity;(2)如果要创建的activity不处于栈顶,此时才会创建一个新的activity入栈,同Standard一样。
生命周期:第一种情况:onCreate 、onStart不会被系统调用,因为他没有什么改变,但是onNewIntent会被调用(activity被正常创建的时候不会调用这个方法);第二种情况同Standard模式。
举个栗子:activity栈中有三个activity,分别是A、B、C。C处于栈顶,且为SingleTop模式。(1)情况1,C中加入点击事件,跳转到C中,此时的结果是复用栈顶的C。(2)情况2,C中加入点击事件跳转到A。结果是创建一个新的A 入栈,A成为栈顶。
三:SingleTask栈内复用模式
说明:如果创建的A activity已经处于栈中,此时不会创建新的Activity,而是会将A activity上面的其他activity摧毁,使得A成为栈顶。
生命周期:同SingleTop模式一样,只会回调一次onNewIntent方法。
举个栗子:此时有A、B、C三个activity,C位于栈顶,启动模式为SingleTask。(1)情况一,C中加入点击事件,跳转到C,此时直接复用栈顶的C Activity。(2)情况二,C跳到A ,会将A之上的所有activity销毁,使A成为 栈顶。
四:SingleInstance单实例模式
说明:全局单例模式,加强版的SingleTask模式。具有所有SingleTask的特性,除此之外,改模式的activity仅仅能单独位于一个任务栈中,这个经常应用于系统的应用中,如,锁屏,Launch等等,整个系统中仅仅有一个。
对Android而言,Activity有四种启动模式,它们是:
1. standard 标准模式也是默认模式,每次都新建一个实例对象。
2. singleTop 如果在任务栈顶发现了相同的实例则重用,否则新建并压入栈顶。
3、singleTask 如果在任务栈中发现了相同的实例,将其上面的任务终止并移除,重用该实例。否则新建实例并入栈。
4、singleInstance 允许不同应用,进程、线程等共用一个实例,无论从何应用调用该实例都重用。
当一个新的activity启动时不会调用goToActivity方法
如果activity不设置启动模式
题主是否想询问“如果activity不设置启动模式会导致什么问题?”会导致运行出现异常、传递错误的问题。根据查询相关信息显示。在应用程序中使用Intent隐式启动Activity时,会出现多个Activity响应同一个Intent的情况,从而导致应用程序运行出现异常。如果Activity需要传递数据给另一个Activity,而另一个Activity已经在任务栈中存在,那么会导致数据传递错误的问题。
Android中的Activity详解--启动模式与任务栈
目录
activity的简单介绍就不写了,作为最常用的四大组件之一,肯定都很熟悉其基本用法了。
首先,是都很熟悉的一张图,即官方介绍的Activity生命周期图.
情景:打开某个应用的的FirstActivity调用方法如下: 由于之前已经很熟悉了,这里就简单贴一些图。
按下返回键:
重新打开并按下home键:
再重新打开:
在其中打开一个DialogActivity(SecondActivity)
按下返回:
修改SecondAcitvity为普通Activity,依旧是上述操作:
这里强调一下 onSaveInstanceState(Bundle outState) 方法的调用时机: 当Activity有可能被系统杀掉时调用,注意,一定是被系统杀掉,自己调用finish是不行的。 测试如下:FirstActivity启动SecondActivity:
一个App会包含很多个Activity,多个Activity之间通过intent进行跳转,那么原始的Activity就是使用栈这个数据结构来保存的。 Task A task is a collection of activities that users interact with when performing a certain job. The activities are arranged in a stack (the back stack ), in the order in which each activity is opened. 即若干个Activity的集合的栈表示一个Task。 当App启动时如果不存在当前App的任务栈就会自动创建一个,默认情况下一个App中的所有Activity都是放在一个Task中的,但是如果指定了特殊的启动模式,那么就会出现同一个App的Activity出现在不同的任务栈中的情况,即会有任务栈中包含来自于不同App的Activity。
标准模式,在不指定启动模式的情况下都是以此种方式启动的。每次启动都会创建一个新的Activity实例,覆盖在原有的Activity上,原有的Activity入栈。 测试如下:在FirstActivity中启动FirstActivity:
当只有一个FirstActivity时堆栈情况:
此种模式下,Activity在启动时会进行判断,如果当前的App的栈顶的Activity即正在活动的Activity就是将要启动的Activity,那么就不会创建新的实例,直接使用栈顶的实例。 测试,设置FirstActivity为此启动模式,多次点击FirstActivity中的启动FirstActivity的按钮查看堆栈情况: (其实点击按钮没有启动新Activity的动画就可以看出并没有启动新Activity)
大意就是: 对于使用singleTop启动或Intent.FLAG_ACTIVITY_SINGLE_TOP启动的Activity,当该Activity被重复启动(注意一定是re-launched,第一次启动时不会调用)时就会调用此方法。 且调用此方法之前会先暂停Activity也就是先调用onPause方法。 而且,即使是在新的调用产生后此方法被调用,但是通过getIntent方法获取到的依旧是以前的Intent,可以通过setIntent方法设置新的Intent。 方法参数就是新传递的Intent.
1.如果是同一个App中启动某个设置了此模式的Activity的话,如果栈中已经存在该Activity的实例,那么就会将该Activity上面的Activity清空,并将此实例放在栈顶。 测试:SecondActivity启动模式设为singleTask,启动三个Activity:
这个模式就很好记,以此模式启动的Activity会存放在一个单独的任务栈中,且只会有一个实例。 测试:SecondActivity启动模式设为singleInstance
结果:
显然,启动了两次ThirdActivity任务栈中就有两个实例,而SecondActivity在另外一个任务栈中,且只有一个。
在使用Intent启动一个Activity时可以设置启动该Activity的启动模式: 这个属性有很多,大致列出几个:
每个启动的Activity都在一个新的任务栈中
singleTop
singleTask
用此种方式启动的Activity,在它启动了其他Activity后,会自动finish.
官方文档介绍如下:
这样看来的话,通俗易懂的讲,就是给每一个任务栈起个名,给每个Activity也起个名,在Activity以singleTask模式启动时,就检查有没有跟此Activity的名相同的任务栈,有的话就将其加入其中。没有的话就按照这个Activity的名创建一个任务栈。 测试:在App1中设置SecondActivity的taskAffinity为“gsq.test”,App2中的ActivityX的taskAffinity也设为“gsq.test”
任务栈信息如下:
结果很显然了。 测试:在上述基础上,在ActivityX中进行跳转到ActivityY,ActivityY不指定启动模式和taskAffinity。结果如下:
这样就没问题了,ActivityY在一个新的任务栈中,名称为包名。 这时从ActivityY跳转到SecondActivity,那应该是gsq.test任务栈只有SecondActivity,ActivityX已经没有了。因为其启动模式是singleTask,在启动它时发现已经有一个实例存在,就把它所在的任务栈上面的Activity都清空了并将其置于栈顶。
还有一点需要提一下,在上面,FirstActivity是App1的lunch Activity,但是由于SecondActivity并没有指定MAIN和LAUNCHER过滤器,故在FirstActivity跳转到SecondActivity时,按下home键,再点开App1,回到的是FirstActivity。
大致就先写这么多吧,好像有点长,废话有点多,估计也有错别字,不要太在意~~~
Activity的启动流程
相关源码:
调用 startActivity 或 startActivityForResult 来启动Activity。那么启动的Activity有两种情况:第一种是启动同进程内的Activity; 第二种是启动不同进程的根Activity,比如在桌面点击启动App,就是启动不同进程的Activity。这两种情况的Activity的启动流程大致相同,其流程大致是以下三个过程:
以下逐一讲解这三大过程:
下图是调用进程向system_server进程发起请求的过程:
startActivityForResult方法继续调用 Instrumentation.execStartActivity 方法。而Instrumentation类主要用来监控应用程序和系统的交互。
下图是ATMS处理startActivity过程,并回调启动进程的ApplicationThread
ATMS. startActivity:
ATMS类通过一系列方法调用最终来到 startActivityAsUser 的方法,该方法先检查调用进程的权限,然后通过 getActivityStartController().obtainStarter 创建 ActivityStarter 类,并把参数设置到 ActivityStarter.Request 类中,最后执行 ActivityStarter.execute() 方法。
ActivityStarter准备堆栈
在 ActivityStarter. executeRequest 方法中先做一系列的检查,包括调用进程的检查、Intent的检查、权限的检查、向PKMS获取启动Activity的ActivityInfo等信息,然后调用 startActivityUnchecked 方法开始对要启动的Activity做堆栈管理。
在 startActivityInner 方法中,根据启动模式计算出flag,在根据flag等条件启动的Activity的ActivityRecord是加入现有的Task栈中,还是创建新Task栈。为Activity准备好堆栈后,调用 RootWindowContainer.resumeFocusedStacksTopActivities 方法
ActivityStack对栈的管理:
对于启动Activity对应的 ActivityStack 来说,是管理其栈中Activity的显示逻辑。而后继续调用 ActivityStackSupervisor.startSpecificActivity
ActivityStackSupervisor检查启动进程和回调ApplicationThread
在ActivityStackSupervisor中先检查要启动Activity的进程是否存在,不存在则创建进程,存在则调用 realStartActivityLocked ,realStartActivityLocked方法通过事务给回调 ApplicationThread. scheduleTransaction 方法。
下图为ActivityThread启动Activity过程的时序图:
ApplicationThread类绕了一大圈,最后调用在ATMS阶段设置的ClientTransaction的CallBack的execute方法,也就是 LaunchActivityItem. execute 方法,此方法创建一个 ActivityClientRecord 对象,然后调用 ActivityThread. handleLaunchActivity 开启真正的Actvity启动。
真正启动Activity:
Activity启动流程笔记
普通Activity的启动就是通过调用startActivity方法启动一个新的Activity,总体流程如下图:
其中涉及到了两个进程,一个是App进程和AMS进程。整体的步骤是:
1.启动者Activity向Instrumentation请求启动目标的Activity。
2. Instrumentation通过AMS在App进程的IBinder接口(IActivityManager)访问AMS,此时App进程会阻塞等待AMS的调用返回,采用的跨进程通信技术是AIDL。
3.AMS会进行一系列的验证工作,如判断目标Activity实例是否存在、启动模式是什么、有没有在AndroidManifest中注册等等。
4.当AMS验证结束后会通过ClinentLifeCycleManager发送事物给App进程,利用App进程在AMS进程的IBinder接口(IApplicationThread)访问App进程ApplicationThread,采用的跨进程通信方式是AIDL。
5.ApplicationThread是ActivityThread的内部类,当ApplicationThread接受到来自AMS的事务后,会将事务直接转交给ActivityThread处理。
6.ActivityThread通过Instrumentation利用类加载器(反射)进行实例的创建,同时利用Instrumentation回调目标Activity的生命周期。
介绍几个关键的类:
Instrumentation:Instrumentation 是 Activity 与外界联系的类(不是 Activity 本身的类都统称为外界)。目标 Activity 通过 Instrumentation 来请求启动,ActivityThread 通过 Instrumentation 来创建 Activity 和回调 Activity 的生命周期。
ActivityThread:每个应用程序只有一个唯一实例,负责对 Activity 创建的管理。ActivityThread 的内部类 ApplicationThread 只负责 App 进程和 AMS 进程的通信,将来自 AMS 的事务交给 ActivityThread 处理。
AMS,全称 ActivityManagerService,系统级服务,负责管理四大组件。
根Actvity就是我们点击手机桌面图标时,应用程序启动的第一个Activity。启动根Activity的流程其实和启动普通Activity的流程类似,只是启动根Activity时需要新建一个App进程。总体流程如下图:
其中涉及到四个进程分别是:Launcher进程、AMS进程、App进程、Zygote进程。
1.点击桌面图标后,Launcher进程访问AMS进程请求启动目标Activity,采用的跨进程方式是AIDL。
2 AMS进程访问Zygote进程请求启动一个新的进程。采用的跨进程方式是Socket。
3 Zygote进程通过调用fork函数创建一个App进程。
4 App进程创建完成后,App进程访问AMS进程进行通知,采用的跨进程方式是AIDL。
5 AMS进程收到来自App进程的通知后,将启动Activity的操作封装成事务,并将封装好的事务发送给App进程。
6 App进程接受到来自AMS进程的事务后,根据事务创建目标Activity,并回调目标Activity的生命周期。
本文主要是用来记录自己的学习笔记,看原文请移步: Activity 启动流程