如何保证Activity实例个数唯一(Activity启动模式)

ActA.java文件:

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);
/**
* standard 模式:
* <p>
* 当使用当前代码块启动Activity时,每次都是新创建了一个Activity实例.
* 因为是使用默认启动模式(标准模式),我们可以通过下面TextView文本中 hash code 来识别是否为新Activity
* 此时点击back可以依次看到先前启动的Activity实例,类似栈退出操作,而启动过程类似压栈操作
*
* singleTop 模式:
* <p>
* 运行的时候会发现,按多少遍按钮,都是相同的ActiA实例,因为该实例在栈顶,因此不会创建新的实例.如果回退,将退出应用
* singleTop模式,可用来解决栈顶多个重复相同的Activity的问题.如果是A Activity跳转到B Activity,再跳转到
* A Activity,行为就和standard一样了,会在B Activity跳转到A Activity的时候创建A
* Activity的新实例,因为当时的 栈顶不是A Activity实例
*
* singleTask 模式:
* <p>
* 当intent到来,需要创建singleTask模式Activity的时候,系统会检查栈里面是否已经有该Activity的实例
* .如果有直接将 intent发送给它.
*
* singleInstance模式:
* <p>
* 首先要说一下Task的概念.如果是Swing或者Windows程序,可能有多个窗口可以切换,但是你无法在自己程序中复用人家的窗口.
* 注意是直接复用人家的二进制代码,不是你拿到人家api后的源代码级调用.Android可以做到,让别人的程序直接复用你的
* Activity(类似桌面程序的窗口).Android为提供这种机制,就引入了Task的概念.
* <p>
* Task可以认为是一个栈,可放入多个Activity.比如启动一个应用,那么Android就创建了一个Task,
* 然后启动这个应用的入口Activity
* ,就是intent-filter中配置为main和launch的那个(见一个APK文件部署产生多个应用安装
* 的效果)这个Activity是根
* (Root)Activity,可能会在它的界面调用其他Activity,这些Activity如果按照上面那三个模式
* ,也会在这个栈(Task)中,只是实例化的策略不同而已. 验证的办法是调用和打印Activity的taskId:   
* <p>
* 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接收和展示.
*
* 这里又有两个问题:
* <p>
* 如果是这种情况,多个task栈也可以看作一个应用.比如导游应用启动地图Activity,
* 实际上是在导游应用task栈之上singleInstance模式创建的
* (如果还没有的话,如果有就是直接显示它)一个新栈,当这个栈里面的唯一Activity
* ,地图Activity回退的时候,只是把这个栈移开了,
* 这样就看到导游应用刚才的Activity了;多个应用(Task)共享一个Activity要求这些应用都没有退出
* ,比如刚才强调要用home键从导游应用切换到地图应用.因为,如果退出导游应用
* .而这时地图应用也并未运行的话,那个单独的地图Activity(task)也会退出了
*
* 如果还是拿刚才的ActA和ActB的示例,可以把ActB的模式改为singleInstance,ActA为standard,进行一下测试
*/
textView.setText("Activity id:" + this + "task Id:" + this.getTaskId());
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文件:

public class ActB 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("Activity id:" + this + "task Id:" + this.getTaskId());
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.setOrientation(LinearLayout.VERTICAL);
layout.addView(textView);
layout.addView(button);
this.setContentView(layout);
}

protected void onDestory(){
super.onDestroy();
System.out.println("____B ondestory_____");
}

}


AndroidMenifest.xml文件(配置启动模式):

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.model" android:versionCode="1"
android:versionName="1.0">
<application android:icon="@drawable/icon" android:label="@string/app_name">
<activity android:name=".ActA" android:label="@string/app_name"
android:launchMode="singleTask">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".ActB" android:launchMode="singleInstance" />
</application>
</manifest>


这个url写下供自己参考,当然大伙都可以链过去学习学习:

[url]http://winuxxan.blog.51cto.com/2779763/504047[/url]
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值