Android Activity的4种启动模式详解(示例)
转载请注明出处:http://www.cnblogs.com/Joanna-Yan/p/5233269.html
先介绍下Android对Activity的管理,Android采用Task来管理多个Activity,当我们启动一个应用时,Android就会为之创建一个Task,然后启动这个应用的入口Activity(即<intent-filter.../>中配置为 MAIN和LAUNCHER的Activity)。
因为Android并没有为Task提供API,因此我们无法真正去访问Task,只能调用Activity的getTaskId()方法来获取它所在的Task的ID。事实上我们可以把Task理解成Activity栈,Task以栈的形式来管理Activity:先启动的Activity被放在Task栈底,后启动的Activity被放在Task栈顶。
那么Activity的加载模式,就负责管理实例化、加载Activity的方式、并可以控制Activity与Task之间的关系。
Activity有4中启动模式,分别为:standard,singleTop,singleTask,singleInstance。如果要使用这四种启动模式,必须在manifest文件中<activity>标签中的launchMode属性配置,如:
<activity
android:name=".MainActivity"
android:label="@string/app_name"
android:launchMode="standard"
>
</activity>
standard
标准启动模式,也是Android的默认启动模式。在这种模式下启动的activity可以被多次实例化,即在一个任务中可以存在多个activity实例,每个实例都会处理一个Intent对象。如果Activity A的启动模式为standard,并且A已经启动,在A中再次启动Activity A,即调用startActivity(new Intent(this,A.class)),会在A的上面再次启动一个A的实例,即当前的栈中的状态为A-->A。
singleTop
如果一个以singleTop模式启动的activity的实例已经存在于任务栈的栈顶,那么再次启动这个activity时,不会创建新的实例,而是重用位于栈顶的那个实例,并且会调用该实例的onNewIntent()方法将Intent对象传递到这个实例中。举例来说,如果A的启动模式为singleTop,并且A的一个实例已经存在于栈顶中,那么再调用startActivity(new Intent(this,A.class))启动A时,不会再创建A的实例,而是重用原来的实例,并且调用原来实例的onNewIntent()方法。这时任务栈中还是有一个A的实例。
如果以singleTop模式启动的activity的一个实例已经存在于任务栈中,但是不在栈顶,那么它的行为和standard模式相同,也会创建多个实例。
singleTask
官方文档上称,如果一个activity的启动模式为singleTask,那么系统总会在一个新的任务的最底部(root)启动这个activity,并且被这个activity启动的其它activity会和该activity同时存在于这个新任务中。如果系统中已经存在一个这样的activity则会重用这个实例,并且调用它的onNewIntent()方法。即,这样的一个activity在系统中只会存在一个实例。
但是这种说法并不准确,采用singleTask启动目标Activity时,可分三种情况:
1、如果将要开启的目标Activity不存在,系统将会创建目标Activity实例,并将它放入Task栈顶。
2、如果将要启动的目标Activity已经位于Task栈顶,此时与singleTop模式的行为相同。
3、如果将要启动的目标Activity已经存在、但没有位于Task栈顶,系统将会把位于该Activity上面的所有Activity移出Task栈,从而使得目标Activity转入栈顶。
下面通过实例说明:
两个Activity,FirstActivity显示文本框和按钮,该按钮用于启动SecondActivity;SecondActivity显示文本框和按钮,该按钮用于启动FirstActivity。
public class FirstActivity extends Activity {
TextView tv;
Button btn;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); tv=(TextView) findViewById(R.id.tv);
tv.setText("Activity为:"+this.toString()+",Task ID为:"+this.getTaskId());
btn=(Button) findViewById(R.id.btn);
btn.setOnClickListener(new View.OnClickListener() { @Override
public void onClick(View v) {
Intent intent=new Intent(FirstActivity.this, SecondActivity.class);
startActivity(intent);
}
});
}
}
public class SecondActivity extends Activity {
TextView tv;
Button btn;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second); tv=(TextView) findViewById(R.id.tv);
tv.setText("Activity为:"+this.toString()+",Task ID为:"+this.getTaskId());
btn=(Button) findViewById(R.id.btn);
btn.setOnClickListener(new View.OnClickListener() { @Override
public void onClick(View v) {
Intent intent=new Intent(SecondActivity.this, FirstActivity.class);
startActivity(intent);
}
});
}
}
运行该实例,系统默认启动FirstActivity,点击该界面按钮,系统以singgleTask模式打开SecondActivity ,此时Task栈中有两个Activity(从底向上):FirstActivity-->SecondActivity.
点击SecondActivity界面按钮,系统以标准模式再次启动FirstActivity,此时Task栈中有三个Activity(从底向上):FirstActivity-->SecondActivity-->FirstActivity.
在FirstActivity中再次点击按钮,系统以singleTask模式再次打开SecondActivity,系统会将位于SecondActivity上面的所有Activity移出,使得SecondActivity进入栈顶,此时Task栈中只有两个Activity(从底向上):FirstActivity-->SecondActivity.
效果图(依次):
singleInstance
总是在新的任务中开启,并且这个新的任务中有且只有这一个实例,也就是说被该实例启动的其他activity会自动运行于另一个任务中。当再次启动该activity的实例时,会重用已存在的任务和实例。并且会调用这个实例的onNewIntent()方法,将Intent实例传递到该实例中。和singleTask相同,同一时刻在系统中只会存在一个这样的Activity实例。
说明:
这种加载模式下,系统保证无论从哪个Task中启动目标Activity,只会创建一个目标Activity实例,并会使用一个全新的Task栈来装载该Activity实例。
当用singleInstance启动目标Activity时,分两种情况:
1、当将要启动的目标Activity不存在,系统会先创建一个全新的Task、再创建目标Activity的实例,并将它加入新的Task的栈顶。
2、如果将要启动的目标Activity已经存在,无论它位于哪个应用程序中,无论它位于哪个Task中,系统将会把该Activity所在的Task转到前台,从而使用该Activity显示出来。
采用该模式加载的Activity总是位于Task栈顶,所在Task只包含该Activity.
举例说明:
点击FirstActivity中按钮,启动SecondActivity。SecondActivity配置成singleInstance加载模式,export属性配置成true---表明该Activity可被其它应用启动。
public class FirstActivity extends Activity {
TextView tv;
Button btn;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); tv=(TextView) findViewById(R.id.tv);
tv.setText("Activity为:"+this.toString()+",Task ID为:"+this.getTaskId());
btn=(Button) findViewById(R.id.btn);
btn.setOnClickListener(new View.OnClickListener() { @Override
public void onClick(View v) {
Intent intent=new Intent(FirstActivity.this, SecondActivity.class);
startActivity(intent);
}
});
}
}
<activity
android:name=".SecondActivity"
android:launchMode="singleInstance"
android:exported="true" >
<intent-filter>
<!--知道该Activity能响应Action为指定字符串的Intent -->
<action android:name="joanna.yan.action.TEST_ACTION" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
系统启动新的Task并用新的Task加载新创建的SecondActivity实例,SecondActivity总是位于栈顶。
效果图:
另一个示例采用隐式Intent再次启动该SecondActivity。
代码:
public class OtherActivity extends Activity {
TextView tv;
Button btn;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second); tv=(TextView) findViewById(R.id.tv);
tv.setText("Activity为:"+this.toString()+",Task ID为:"+this.getTaskId());
btn=(Button) findViewById(R.id.btn);
btn.setOnClickListener(new View.OnClickListener() { @Override
public void onClick(View v) {
Intent intent=new Intent();
intent.setAction("joanna.yan.action.TEST_ACTION");
startActivity(intent);
}
});
}
}
单击OtherActivity中的按钮隐式启动singleInstance模式的SecondActivity,如果前面一个示例还未退出,无论SecondActivity所在Task是否位于前台,系统将再次把SecondActivity所在Task转入前台,从而将SecondActivity显示出来。
效果图:
如果此文对您有帮助,微信打赏我一下吧~
Android Activity的4种启动模式详解(示例)的更多相关文章
- Activity的四种启动模式详解
Activity的启动模式在清单文件AndroidManifest.xml中的Activity属性中进行设置: 如:<activity android:name=".MainActiv ...
- Android Activity 的四种启动模式 lunchMode 和 Intent.setFlags();singleTask的两种启动方式。
原文:Android Activity 的四种启动模式 lunchMode 和 Intent.setFlags();singleTask的两种启动方式. Android Activity 的四种启动模 ...
- Android Activity的4种启动模式
Activity的启动模式 standard 默认标志的启动模式,每次startActivity都是创建一个新的activity的实例,适用于绝大数情况 singleTop 单一顶部,如果要开启的ac ...
- UEFI与 Legacy BIOS两种启动模式详解
(1). UEFI启动模式 与 legacy启动模式 legacy启动模式: 就是这么多年来PC一直在使用的启动方式(从MBR中加载启动程序),UEFI BIOS作为一种新的BIOS自然也应该兼容这种 ...
- Android中Activity启动模式详解
在Android中每个界面都是一个Activity,切换界面操作其实是多个不同Activity之间的实例化操作.在Android中Activity的启动模式决定了Activity的启动运行方式. An ...
- 详解Activity的四种启动模式
在Android中每个界面都是一个Activity,切换界面操作其实是多个不同Activity之间的实例化操作.在Android中Activity的启动模式决定了Activity的启动运行方式. Ac ...
- Android Activity 启动模式详解
最近有群里的朋友问我 Activity的四种启动模式分别是什么意思? 当初因为项目比较忙,草草的解释了下, Api文档中说的也只是一般,在这里就小记一下吧,以便有更多的朋友对Activity启动模式了 ...
- Android 关于Activity的四种启动模式的简单介绍
Activity启动模式设置: <activity android:name=".MainActivity" android:launchMode="standar ...
- Android学习笔记四:activity的四种启动模式
Activity有四种启动模式:standard,singleTop,singleTask,singleInstance. 1.standard:标准启动模式 默认模式,这个模式下启动的Activit ...
随机推荐
- “不给力啊,老湿!”:RSA加密与破解
作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! 加密和解密是自古就有技术了.经常看到侦探电影的桥段,勇敢又机智的主角,拿着一长串毫 ...
- Vue-Router 页面正在加载特效
Vue-Router 页面正在加载特效 如果你在使用 Vue.js 和 Vue-Router 开发单页面应用.因为每个页面都是一个 Vue 组件,你需要从服务器端请求数据,然后再让 Vue 引擎来渲染 ...
- Power BI官方视频(3) Power BI Desktop 8月份更新功能概述
Power BI Desktop 8月24日发布了更新版本.现将更新内容翻译整理如下,可以根据后面提供的链接下载最新版本使用. 1.主要功能更新 1.1 数据钻取支持在线版 以前的desktop中进行 ...
- 13、零配置Struts2开发
Convention 插件 从 Struts 2.1 开始, Struts 可以使用 Convention 插件来支持零配置: Convention 插件完全抛弃配置信息, 不仅不需要使用 strut ...
- [C#][算法] 用菜鸟的思维学习算法 -- 马桶排序、冒泡排序和快速排序
用菜鸟的思维学习算法 -- 马桶排序.冒泡排序和快速排序 [博主]反骨仔 [来源]http://www.cnblogs.com/liqingwen/p/4994261.html 目录 马桶排序(令人 ...
- https 安全验证问题
最近为了满足苹果的 https 要求, 经过努力终于写出了方法 验证 SSL 证书是否满足 ATS 要求 nscurl --ats-diagnostics --verbose https://你的域名 ...
- github免输用户名/密码SSH登录的配置
从github上获取的,自己整理了下,以备后用. Generating an SSH key mac windows SSH keys are a way to identify trusted co ...
- SVG:textPath深入理解
SVG的文本可以沿着一条自定义的Path来排布,比如曲线.圆形等等,使用方式如下所示(来源MDN): <svg viewBox="0 0 1000 300" xmlns=&q ...
- 关于我 — About Me
个人简介 姓名:周旭龙 关注:.NET开发技术.Web前端技术 邮箱:edisonchou@hotmail.com GitHub: https://github.com/edisonchou 主要经历 ...
- C++ std::priority_queue
std::priority_queue template <class T, class Container = vector<T>, class Compare = less< ...