发布网友 发布时间:2022-04-25 20:48
共1个回答
热心网友 时间:2022-06-17 06:55
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文件(配置启动模式):
<?