Android开发笔记(十六)——Activity的4种启动模式

AndroidManifest 中比较重要的一个属性是 launchMode 启动模式:

Acyivity的 android:launchMode 四个属性:

  • standard:标准模式,默认
  • singleTop:Task栈顶复用模式(栈是先进后出,当我们启动一个Activity,如果这个目标Activity位于栈顶,不会创建一个新的实例,而是会直接复用这个栈顶的Activity)
  • singleTask:Task栈内复用模式(不一定要在栈顶,只要栈内有就可以直接复用,不管位置)
  • singleInstance:全局单例模式(前两个必须是在同一个栈内,这个是只要在存取的所有栈里面只要有的就可以复用)

测试准备

继续使用上次创建的AActivity和BActivity。

在AActivity中的onCreate函数中添加:

Log.d("AActivity","-----onCreate-----");
Log.d("AActivity","---taskid:"+getTaskId()+"---   ---hash:"+hashCode()+"---");
logtaskName();  //打印任务栈的名称

onNewIntentlogtaskName 函数写在onCreate函数后面:

    @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        Log.d("AActivity","-----onNewIntent-----");
        Log.d("AActivity","---taskid:"+getTaskId()+"---   ---hash:"+hashCode()+"---");
        logtaskName();  //打印任务栈的名称
    }

    private void logtaskName(){
        try {
            ActivityInfo info = getPackageManager().getActivityInfo(getComponentName(), PackageManager.GET_META_DATA);
            Log.d("AActinity",info.taskAffinity); //info.taskAffinity可以理解为当前Activity所在任务栈的名称
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
        }
    }

在BActivity中同样操作,在A添加一个Button使其在A页面跳转到A页面,在B添加一个Button使其在B页面跳转到A页面。

standard

  • Activity是由任务栈管理的,每启动一个Activity,就会被放入栈中,按返回键,就会从栈顶移除一个Activity。
  • standard是默认的启动模式,即标准模式。每启动一个Activity,都会创建一个新的实例。

演示

  • 从主页面MainActivity跳转到AActivity中时,MainActivity的任务栈为包名,后面所有的Activity都隶属于这个栈
  • 当没有设置任务栈的名称时候,默认为应用的包名
  • 当点击Button从A页面跳转到A页面时,这里taskid是一样的,也就是这两个Activity处在同一个任务栈当中,但是他们的哈希码是不一样的,表示这两个Activity不是同一个实例,说明从A页面跳转到A页面时又创建了一个新的实例。(因为是标准启动,每启动一个Activity,都会创建一个新的实例
  • 当点击Jump从A页面跳转到B页面时:可以看到任务栈还是相同的,但是哈希码不同,因为BActivity本身不存在于任务栈当中,是一个新的实例

singleTop

  • 当要启动的目标Activity已经位于栈顶时,不会创建新的实例,会复用栈顶的Activity,并且其 onNewIntent() 方法会被调用;
  • 如果目标Activity不在栈顶(在栈里但不在顶部;或者根本不在栈内),则和standard一样创建新的实例。

演示

  • 从主页面MainActivity跳转到AActivity中时,调用onCreate方法
  • 从AActivity再次跳转到AActivity中时(此时目标Activity是AActivity,目标Activity在栈顶中),这时打印出来的哈希码和之前一直,也就是说此时复用了栈顶的Activity,并且其onNewIntent()方法被调用
  • 从AActivity跳转到BActivity中时(此时目标Activity是BActivity,目标Bctivity不在栈中),此时哈希码发生了变化,说明创建了新的实例。
  • 从BActivity再次跳转到AActivity中时(此时目标Activity是AActivity,目标Activity在栈中但是不在栈顶中),此时哈希码发生了变化,说明创建了新的实例。

singleTask

  • 在同一个任务栈中,如果要启动的目标Activity已经在栈中,则会复用该Activity,并调用其 onNewIntent() 方法,并且该Activity上面的Activity会被清除(出栈)
  • 如果栈中没哟,则创建新的实例。

当没有设置任务栈的名称时候,默认为应用的包名,如果自己有设置任务栈名称(在 AndroidManifast 中对应的activity设置属性 android:taskAffinity ),那就不属于默认包名的任务栈了。当从这个Activity开始启其他Activity时候,都会被加入这个新设置的栈中。

singleInstance

  • 全局复用,不管哪个Task栈,只要存在目标Activity就复用;
  • 每个Activity占有一个新的Task栈。

通常使用standard和singleTop、singleTask,singleInstance用的比较少。

posted @ 2020-07-21 17:52  Ylxxxxx  阅读(193)  评论(0编辑  收藏  举报