Android之Activity LaunchMode

来源:互联网 发布:最新在线报名系统源码 编辑:程序博客网 时间:2024/05/22 13:07

背景:

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

这种需求需要通过配置Activity的LaunchMode来实现。


Activity有四种加载模式:

1.standard(标准模式,此项是默认的加载模式)

在此种模式情况下的Activity会每次都生成新的实例


我们首先定义了A这个Activity,然后它的内容如下:

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.TextView;public class A extends Activity implements OnClickListener {private TextView textView01;private Button btn01;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_a);textView01 = (TextView) findViewById(R.id.tv_01);btn01 = (Button) findViewById(R.id.button1);btn01.setOnClickListener(this);//获取当前Activity的任务栈IDint taskID = A.this.getTaskId();//获取当前Activity实例的详细信息String objectMsg = A.this.toString();//将信息输出到屏幕上textView01.setText("当前任务栈ID:" + taskID + "\r\n"  + "当前Activity实例信息:"+ objectMsg);}@Overridepublic void onClick(View v) {switch (v.getId()) {case R.id.button1://开始跳转ActivityIntent intent = new Intent(A.this, A.class);startActivity(intent);break;default:break;}}}


在程序运行之后,我们点击2次《跳转到A》这个按钮,会发现三个不同的界面:


             


观察发现:这三个A同属于一个任务栈,因为栈的ID都相同,但是他们的实例名称都不一样,说明这个任务栈中现在已经存在了三个不同的A实例;如果此时点击手机上的《返回》按键,那么需要连续点击三次才能退出程序。


将以上总结为流程图如下:



2.singleTop模式

在此种模式下,

如果A在任务栈顶,那么A跳转到A将不生成新的实例,直接跳转到现在的栈顶A;

如果A不在任务栈顶,那么其他的Activity去跳转到A,将生成新的A实例;


我们在代码中定义两个Activity,分别是A和B,以上是这两个Activity的定义,其中A的launchMode属性被设置为singleTop。

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.TextView;public class A extends Activity implements OnClickListener {private TextView textView01;private Button btn01;private Button btn02;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_a);textView01 = (TextView) findViewById(R.id.tv_01);btn01 = (Button) findViewById(R.id.button1);btn01.setOnClickListener(this);btn02 = (Button) findViewById(R.id.button2);btn02.setOnClickListener(this);//获取当前Activity的任务栈IDint taskID = A.this.getTaskId();//获取当前Activity实例的详细信息String objectMsg = A.this.toString();//将信息输出到屏幕上textView01.setText("当前任务栈ID:" + taskID + "\r\n"  + "当前Activity实例信息:"+ objectMsg);}@Overridepublic void onClick(View v) {switch (v.getId()) {case R.id.button1://A--->AIntent intent01 = new Intent(A.this, A.class);startActivity(intent01);break;case R.id.button2://A---->BIntent intent02 = new Intent(A.this, B.class);startActivity(intent02);break;default:break;}}}


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.TextView;public class B extends Activity implements OnClickListener {private TextView textView01;private Button btn01;private Button btn02;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_a);textView01 = (TextView) findViewById(R.id.tv_01);btn01 = (Button) findViewById(R.id.button1);btn01.setOnClickListener(this);btn02 = (Button) findViewById(R.id.button2);btn02.setOnClickListener(this);//获取当前Activity的任务栈IDint taskID = B.this.getTaskId();//获取当前Activity实例的详细信息String objectMsg = B.this.toString();//将信息输出到屏幕上textView01.setText("当前任务栈ID:" + taskID + "\r\n"  + "当前Activity实例信息:"+ objectMsg);}@Overridepublic void onClick(View v) {switch (v.getId()) {case R.id.button1://B--->AIntent intent01 = new Intent(B.this, A.class);startActivity(intent01);break;case R.id.button2://B---->BIntent intent02 = new Intent(B.this, B.class);startActivity(intent02);break;default:break;}}}


在程序运行后,我们点击跳转到A,界面不会有任何变化,说明当A在任务栈顶时,你发送跳转到A的Intent,那么这个Intent会发送给栈顶的A实例;

以下三张图片展示的流程是A---->B---->A:

       


观察发现:这三个Activity实例是不同的实例,但是他们同属一个任务栈,因为他们的任务栈ID相同;我们这里可以很明显的发现,当B在栈顶的时候,跳转到A,会生成新的A实例。


将以上总结为流程图如下:



3.singleTask模式

在此种模式,任务栈中只能有一个A实例,不管它在任务栈的什么位置;

这里我们应当注意:当A在栈顶时,直接跳转到A实例;当A不在栈顶时,将会发生的事情是,在A之上的所有Activity实例被弹出任务栈,直至A到达栈顶。


本次仍然沿用上一次的代码,只是在manifest中将A的launchMode配置为singleTask,在B中添加一个Button跳转到C,然后C中只有一个按钮,这个按钮的作用是跳转到A。

以下四张图片展示了A---->B---->C---->A:

  

 


观察以上结果我们可以发现:总共有三个实例,A、B、C各一个,当C在栈顶的时候,跳转到A,我们会返现,Intent会直接发送到栈底的A实例,并且将B、C两个实例弹栈。


将以上总结为流程图如下:



4.singleInstance模式

此Activity加载模式是为了解决这样一类问题:

在同一App中,当有一个Activity需要被多个Activity共享(即是多个Activity可以跳转到这个Activity),那么我们肯定希望此Activity长期处于Alive状态,并且是同一个实例(这样更能节省手机资源),但是同一app中,所有的Activity实例都在同一个任务栈中,我们会发现,经常性的压栈和弹栈使我们无法确定此Activity会在什么时候被弹栈销毁掉了,这个时候我们可以通过将此Activity的加载模式设置为singleInstance来满足这样的需求,当设置为此模式后,此Activity被单独在一个任务栈中维护,而不受主任务栈中频繁的压栈和弹栈操作的影响。


其实写到这个地方我觉得文字的表现力始终不及图形,首先我们来看一下,将B的launchmode设置为singleInstance,然后再来分析以下的图片结果:

      

分析以上结果我们会发现:B实例的任务栈ID,与A实例所在的任务栈ID不相同,说明他们处于不同的任务栈中;

并且这只是一种情况,实际这里有好几种情况,我将其总结到下面这张图中,希望能够对读者真的产生帮助;


写这篇文章的时候我想起了古人的一句话,纸上得来终觉浅,绝知此事要躬行,网上流行一篇讲LaunchMode的文章,全是用蓝色的图解,实际上我很受益于这篇文章,但是当我写这篇文章的时候我发现“我认为以前的我完全懂了”是不全面的,我对LauchMode似乎有了新的认识,感谢实践!!!


下面来本篇最后一张我绘的流程图:




例行公事,把代码链接放这里:

Android Activity LaunchMode

1 0
原创粉丝点击