区分Activity的四种加载模式-activity

转载:http://marshal.easymorse.com/archives/2950

 

在多Activity开发中,有可能是自己应用之间的Activity跳转,或者夹带其他应用的可复用Activity。可能会希望跳转到原来某个Activity实例,而不是产生大量重复的Activity。

这需要为Activity配置特定的加载模式,而不是使用默认的加载模式。

加载模式分类及在哪里配置

Activity有四种加载模式:

  • standard
  • singleTop
  • singleTask
  • singleInstance

设置的位置在AndroidManifest.xml文件中activity元素的android:launchMode属性:

<activity android:name="ActB" android:launchMode="singleTask"></activity>

也可以在Eclipse ADT中图形界面中编辑:

image

 

区分Activity的加载模式,通过示例一目了然。这里编写了一个Activity A(ActA)和Activity B(ActB)循环跳转的例子。对加载模式修改和代码做稍微改动,就可以说明四种模式的区别。

standard

首先说standard模式,也就是默认模式,不需要配置launchMode。先只写一个名为ActA的Activity:

Java代码
    package com.easymorse.activities;  import android.app.Activity;  import android.content.Intent;  import android.os.Bundle;  import android.view.View;  import android.view.View.OnClickListener;  import android.widget.Button;  import android.widget.LinearLayout;  import android.widget.TextView;  public class ActA extends Activity {  /** Called when the activity is first created. */  @Override  public void onCreate(Bundle savedInstanceState) {  super.onCreate(savedInstanceState);  TextView textView = new TextView(this);  textView.setText(this + "");  Button button = new Button(this);  button.setText("go actA");  button.setOnClickListener(new OnClickListener() {  @Override  public void onClick(View v) {  Intent intent = new Intent();  intent.setClass(ActA.this, ActA.class);  startActivity(intent);  }  });  LinearLayout layout = new LinearLayout(this);  layout.setOrientation(LinearLayout.VERTICAL);  layout.addView(textView);  layout.addView(button);  this.setContentView(layout);  }  }  

 

例子中都没有用layout,免得看着罗嗦。可见是ActA –> ActA的例子。在界面中打印出对象的toString值可以根据hash code识别是否创建新ActA实例。

第一个界面:

image

点击按钮后:

image

可以多点几次。发现每次都创建了该Activity的新实例。standard的加载模式就是这样的,intent将发送给新的实例。

现在点Android设备的回退键,可以看到是按照刚才创建Activity实例的倒序依次出现,类似退栈的操作,而刚才操作跳转按钮的过程是压栈的操作。如下图:

image

singleTop

singleTop和standard模式,都会将intent发送新的实例(后两种模式不发送到新的实例,如果已经有了的话)。不过,singleTop要求如果创建intent的时候栈顶已经有要创建的Activity的实例,则将intent发送给该实例,而不发送给新的实例。

还是用刚才的示例,只需将launchMode改为singleTop,就能看到区别。

运行的时候会发现,按多少遍按钮,都是相同的ActiA实例,因为该实例在栈顶,因此不会创建新的实例。如果回退,将退出应用。

image

singleTop模式,可用来解决栈顶多个重复相同的Activity的问题。

如果是A Activity跳转到B Activity,再跳转到A Activity,行为就和standard一样了,会在B Activity跳转到A Activity的时候创建A Activity的新实例,因为当时的栈顶不是A Activity实例。

ActA类稍作改动:

Java代码
    package com.easymorse.activities;  import android.app.Activity;  import android.content.Intent;  import android.os.Bundle;  import android.view.View;  import android.view.View.OnClickListener;  import android.widget.Button;  import android.widget.LinearLayout;  import android.widget.TextView;  public class ActA extends Activity {  /** Called when the activity is first created. */  @Override  public void onCreate(Bundle savedInstanceState) {  super.onCreate(savedInstanceState);  TextView textView = new TextView(this);  textView.setText(this + "");  Button button = new Button(this);  button.setText("go actB");  button.setOnClickListener(new OnClickListener() {  @Override  public void onClick(View v) {  Intent intent = new Intent();  intent.setClass(ActA.this, ActB.class);  startActivity(intent);  }  });  LinearLayout layout = new LinearLayout(this);  layout.setOrientation(LinearLayout.VERTICAL);  layout.addView(textView);  layout.addView(button);  this.setContentView(layout);  }  }  

 

 

ActB类:

Java代码
    package com.easymorse.activities;  import android.app.Activity;  import android.content.Intent;  import android.os.Bundle;  import android.view.View;  import android.view.View.OnClickListener;  import android.widget.Button;  import android.widget.LinearLayout;  public class ActB extends Activity {  @Override  protected void onCreate(Bundle savedInstanceState) {  super.onCreate(savedInstanceState);  Button button=new Button(this);  button.setText("go actA");  button.setOnClickListener(new OnClickListener() {  @Override  public void onClick(View v) {  Intent intent=new Intent();  intent.setClass(ActB.this, ActA.class);  startActivity(intent);  }  });  LinearLayout layout=new LinearLayout(this);  layout.addView(button);  this.setContentView(layout);  }  }  

 

 

ActB类使用默认(standard)加载,ActA使用singleTop加载。结果类似下图:

image

如果把ActA的加载模式改为standard,情况一样。

singleTask

singleTask模式和后面的singleInstance模式都是只创建一个实例的。

当intent到来,需要创建singleTask模式Activity的时候,系统会检查栈里面是否已经有该Activity的实例。如果有直接将intent发送给它。

把上面singleTop的实例中的ActA的launchMode改为singleTask,ActB的改为standard。那么会发现在ActA界面中按一次按钮:

image

然后在ActB1界面中按按钮,因为ActA是singleTask,会使用原来的ActA1实例。这时候栈内的情况:

image

如果多次按按钮跳转,会发现始终只有ActA1这一个ActA类的实例。

singleInstance

解释singleInstance模式比较麻烦。

首先要说一下Task(任务)的概念。

如果是Swing或者Windows程序,可能有多个窗口可以切换,但是你无法在自己程序中复用人家的窗口。注意是直接复用人家的二进制代码,不是你拿到人家api后的源代码级调用。

Android可以做到,让别人的程序直接复用你的Activity(类似桌面程序的窗口)。

Android为提供这种机制,就引入了Task的概念。Task可以认为是一个栈,可放入多个Activity。比如启动一个应用,那么Android就创建了一个Task,然后启动这个应用的入口Activity,就是intent-filter中配置为main和launch的那个(见一个APK文件部署产生多个应用安装的效果)。这个Activity是根(Root)Activity,可能会在它的界面调用其他Activity,这些Activity如果按照上面那三个模式,也会在这个栈(Task)中,只是实例化的策略不同而已。

验证的办法是调用和打印Activity的taskId:

TextView textView2 = new TextView(this);
textView2.setText("task id: "+this.getTaskId());

会发现,无论切换Activity,taskId是相同的。

当然也可以在这个单一的Task栈中,放入别人的Activity,比如google地图,这样用户看过地图按回退键的时候,会退栈回到调用地图的Activity。对用户来说,并不觉得在操作多个应用。这就是Task的作用。

但是,有这样的需求,多个Task共享一个Activity(singleTask是在一个task中共享一个Activity)。

现成的例子是google地图。比如我有一个应用是导游方面的,其中调用的google地图Activity。那么现在我比如按home键,然后到应用列表中打开google地图,你会发现显示的就是刚才的地图,实际上是同一个Activity。

如果使用上面三种模式,是无法实现这个需求的。google地图应用中有多个上下文Activity,比如路线查询等的,导游应用也有一些上下文Activity。在各自应用中回退要回退到各自的上下文Activity中。

singleInstance模式解决了这个问题(绕了这么半天才说到正题)。让这个模式下的Activity单独在一个task栈中。这个栈只有一个Activity。导游应用和google地图应用发送的intent都由这个Activity接收和展示。

这里又有两个问题:

  • 如果是这种情况,多个task栈也可以看作一个应用。比如导游应用启动地图Activity,实际上是在导游应用task栈之上singleInstance模式创建的(如果还没有的话,如果有就是直接显示它)一个新栈,当这个栈里面的唯一Activity,地图Activity回退的时候,只是把这个栈移开了,这样就看到导游应用刚才的Activity了;
  • 多个应用(Task)共享一个Activity要求这些应用都没有退出,比如刚才强调要用home键从导游应用切换到地图应用。因为,如果退出导游应用,而这时也地图应用并未运行的话,那个单独的地图Activity(task)也会退出了。

如果还是拿刚才的ActA和ActB的示例,可以把ActB的模式改为singleInstance,ActA为standard,如果按一次按钮切换到ActB,看到现象用示意图类似这样:

image

如果是第一次按钮切换到ActB,在ActB在按按钮切换到ActA,然后再回退,示意图是:

image

另外,可以看到两个Activity的taskId是不同的


转载于:https://www.cnblogs.com/java20130722/archive/2012/08/28/3207324.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/494743.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Nature:AI为什么总是歧视重重?

来源&#xff1a;网络大数据摘要&#xff1a;当使用谷歌翻译将西班牙语的新闻翻译为英语时&#xff0c;涉及到女性的短语通常都会翻译为“他说”或“他写道”。当使用谷歌翻译将西班牙语的新闻翻译为英语时&#xff0c;涉及到女性的短语通常都会翻译为“他说”或“他写道”。常…

※【python自学】7个Python生态系统核心库,你值得拥有

无论你是想快速入手Python&#xff0c;还是想成为数据分析大神或者机器学习大佬&#xff0c;亦或者对Python代码进行优化&#xff0c;本文的python库都能为你提供一些帮助。 一 概述 Python生态系统的一些核心基础数据分析库&#xff1a; NumPy&#xff1a;支持大量的维度数…

Eclipse编写Java程序

Eclipse的Java开发工具(JDT),允许用户使用它的环境进行编辑、调试及运行Java程序。1. Java运行环境设置 指定JRE的版本。Eclipse设置默认的运行环境的JRE设置成当前配置&#xff0c;用户可以修改多个JRE版本的运行环境&#xff0c;并选择符合其需求的运行环境。[窗口 Window]…

㊙️【教你用python挣零花钱】自动化简历内推,学弟直呼牛逼!!

最近&#xff0c;小编在处理简历时&#xff0c;发现大量简历需要一个个打开文件&#xff0c;复制姓名、邮箱、电话号码、学历等关键信息&#xff0c;效率特别低且部分文件无法直接复制。于是&#xff0c;小编便写了简历解析处理的脚本&#xff0c;支持文件格式有&#xff1a;do…

MySQL流浪记(六)—— CONCAT到GROUP_CONCAT的沿途风景(图文详解)

本文中的案例如下&#xff0c;可以自己测试一下&#xff0c;有问题可以留言哦。 CREATE TABLE staff (id INT PRIMARY KEY AUTO_INCREMENT,name VARCHAR(50),job_id INT, joindate DATE,salary DECIMAL(7,2) ); INSERT INTO staff(name,job_id,joindate,salary) VALUES (孙悟…

收藏!最新大数据产业地图 十大生态金矿百大公司起底【附下载】

来源&#xff1a;智东西人工智能的崛起&#xff0c;加速了大数据技术的应用落地。据中国大数据产业生态联盟调查显示&#xff0c;国内大数据企业年营业额4000万人民币以上的已经超过40%&#xff0c;这意味着&#xff0c;这些企业已经度过生存期&#xff0c;开始进入应用落地和品…

【一鸣离职,左晖去世】互联网老兵给大家的三个建议

2021年5月20日&#xff0c;除了娱乐圈的分分合合&#xff0c;互联网圈发生了两件大事&#xff1a; 1、字节跳动创始人张一鸣发布内部全员信&#xff0c;宣布卸任CEO一职。 2、贝壳发布讣告&#xff0c;公司创始人兼董事长左晖先生因疾病意外恶化于2021年5月20日…

科大讯飞:让世界听见AI的声音

来源&#xff1a;华为怀揣着“让世界聆听我们的声音”的梦想&#xff0c;科大讯飞依托世界领先的核心技术&#xff0c;引领智能浪潮&#xff0c;服务亿万用户&#xff0c;从中国语音产业的拓荒者一跃成为世界人工智能产业的领军者&#xff0c;而最初科大讯飞把语音作为切入点却…

Linux中的chmod详解

chmod&#xff08;英文全拼&#xff1a;change mode&#xff09;命令是控制用户对文件的权限的命令。Linux/Unix 的文件调用权限分为三级 : 文件所有者&#xff08;Owner&#xff09;、用户组&#xff08;Group&#xff09;、其它用户&#xff08;Other Users&#xff09;。只有…

【程序员薪资】2021年04月新鲜出炉,看看你拖后腿了吗?

程序员一直都是一个备受人们关注的群体。据IDC统计&#xff0c;全球约有1850万名程序员&#xff08;数据还在持续增长&#xff09;&#xff0c;中国占10%左右。随着近年全国互联网创业热潮的兴起&#xff0c;“互联网”、“云计算”以及“智能硬件”等领域发展迅速&#xff0c;…

CICC科普栏目|神经网络浅讲:从神经元到深度学习

图1 人脑神经网络来源&#xff1a; 计算机的潜意识摘要&#xff1a;神经网络是一门重要的机器学习技术。它是目前最为火热的研究方向–深度学习的基础。神经网络是一门重要的机器学习技术。它是目前最为火热的研究方向–深度学习的基础。学习神经网络不仅可以让你掌握一门强大的…

linux安装Redis(超详细,只要三分钟,每一步命令都有命令截图及运行截图)

Redis redis是一个key-value存储系统。和Memcached类似&#xff0c;它支持存储的value类型相对更多&#xff0c;包括string(字符串)、list(链表)、set(集合)、zset(sorted set --有序集合)和hash&#xff08;哈希类型&#xff09;。这些数据类型都支持push/pop、add/remove及取…

鬼才!用Python计算圆周率 π

目录 一、圆周率的历史发展 1、中国 2、印度 3、欧洲 二、用python计算圆周率 A货&#xff1a;什么&#xff01;你不会背圆周率&#xff08;鄙夷的眼神&#xff09; 3.1415926535 8979323846 26433... 桥哥&#xff1a;我会算呀 &#xff01;&#xff01;&#xff01; 一…

大数据常见问题:数据倾斜

offer收割系列介绍&#xff1a; 1、分享桥哥本人或小伙伴在面试大厂时遇到的真题&#xff0c;并给出参考答案&#xff01;&#xff01;如果能帮到大家&#xff0c;点赞、收藏、评论是对我最大的支持&#xff01;&#xff01; 2、涉及岗位&#xff1a;主要为大数据开发、数据仓…

一图看懂新一代人工智能知识体系大全

来源&#xff1a;财经头条摘要&#xff1a;人工智能的发展离不开基础支持层和技术层&#xff0c;基础支持层包括大数据、计算力和算法&#xff1b;技术层包括计算机视觉、语音识别和自然语言处理。人工智能的技术本质是什么&#xff0c;本文会详细分析。人工智能的发展离不开基…

阿里、字节offer收割系列:数据仓库岗(面试真题,建议收藏)

【offer收割系列介绍】 1、分享桥哥本人或小伙伴在面试大厂时遇到的真题&#xff0c;并给出参考答案&#xff01;&#xff01; 2、涉及岗位&#xff1a;主要为大数据开发、数据仓库&#xff08;桥哥干过的&#xff09;&#xff0c;其它岗位也可参考 3、涵盖技术&#xff1a;mys…

MIT新开发的 AI 模型有望改进恶性脑瘤治疗

来源&#xff1a;人工智能和大数据美国研究人员新近开发出一种人工智能模型&#xff0c;能够为胶质母细胞瘤患者设计出最小剂量给药方案&#xff0c;在缩小肿瘤的同时减少药物带来的毒副作用&#xff0c;改进患者生活质量。胶质母细胞瘤是一种常见的恶性脑瘤&#xff0c;常见疗…

建议收藏丨大数据集群常用监控命令(内存、磁盘、CPU、网络)

大家好&#xff0c;我是明月十四桥&#xff01;&#xff01; 擅长领域&#xff1a;python黑科技、大数据后端研发、数据仓库 今日重点&#xff1a; ① 学会查看linux各种状态&#xff0c;包括&#xff1a;网络IO、磁盘、CPU、内存等&#xff1b; ② 学会理解命令所代表的含义&a…

中科院王飞跃:新的智能全球化将要来临,人工智能标准化为时尚早

中国科学院自动化研究所复杂系统管理与控制国家重点实验室主任王飞跃来源&#xff1a;财经网摘要&#xff1a;8月11日&#xff0c;中国科学院自动化研究所复杂系统管理与控制国家重点实验室主任王飞跃在由厚益控股和《财经》杂志联合主办主题为“共享全球智慧 引领未来科技”的…

建议收藏丨sql行转列的一千种写法!!

大家好&#xff0c;我是明月十四桥&#xff01;&#xff01; 爱好特长&#xff1a; 1、爱好和特长有很多&#xff0c;擅长word、excel、ppt、wind等软件的安装与卸载&#xff1b; 2、精通PE、PS、PB、DCF、PEG等单词的拼写&#xff1b; 3、熟悉Windows、Linux、Mac、Android、I…