当前位置:首页 » 安卓系统 » androidactivity启动

androidactivity启动

发布时间: 2024-10-16 04:40:25

Ⅰ 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文件中<activity>标签中的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> 用来保存ActivityRecord,TaskRecord中的mStack表示其所在的ActivityStack,TaskRecord与ActivityStack建立了联系。

       内部维护了一个 ArrayList<TaskRecord> ,用来管理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的状态保持及恢复介绍完毕。

Ⅱ android 怎么设置activity的启动模式

在Android中每个界面都是一个Activity,切换界面操作其实是多个不同Activity之间的实例化操作。在Android中Activity的启动模式决定了Activity的启动运行方式。
Android总Activity的启动模式分为四种:

Activity启动模式设置:

<activity android:name=".MainActivity" android:launchMode="standard" />

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 }

Ⅲ 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的生命周期外,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启动模式的介绍。

欢迎留言指出错误。

热点内容
垫钱算法 发布:2024-11-24 04:42:21 浏览:597
手机存储的其他是什么 发布:2024-11-24 04:40:19 浏览:198
android第三方登录 发布:2024-11-24 04:40:10 浏览:498
数据库硬件要求 发布:2024-11-24 04:37:56 浏览:589
破解加密的word文件 发布:2024-11-24 04:29:20 浏览:51
中国编译器高手 发布:2024-11-24 04:29:20 浏览:114
帝国php 发布:2024-11-24 04:25:04 浏览:502
linuxdnf 发布:2024-11-24 04:20:00 浏览:873
安卓8的手机怎么升级 发布:2024-11-24 04:19:58 浏览:219
redhat连接ftp 发布:2024-11-24 04:19:51 浏览:930