Activity 启动模式全解析

618

前言

开始 Android 知识的复习之路,这篇文章重新整理一下 Activity 的启动模式。前面写过一篇文章,是以图画的形式展示出来的,链接放这里了:图解Android启动模式,看完这一篇就真相大白 。但感觉还不够深了,今天这一次我打算彻底弄懂它。

连新手都知道,Activity 有四种不同的启动模式:

  • Standard :Activity默认的启动模式。
  • singleTop :栈顶复用模式。
  • singleTask :栈内复用模式。
  • singleInstance :单实例模式。

学完本文,你可以知道:四种不同的启动模式的含义,以及它们在各种不同的场景下的使用,下面就一一来看。

Standard

Standard 是 Android 官方默认的启动模式,它是以栈的形式(先进后出)从任务栈中创建和销毁的。下面来看一个demo。

下面是 MainActivity 的代码:

public class MainActivity extends AppCompatActivity {

    public static final String TAG = "MainActivity";
    public static int count = 0;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        count++; //每创建一次就 count++
        Log.d(TAG, "MainActivity 第 " + count + " 次被创建,其哈希码为:" + hashCode());
        findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(MainActivity.this, MainActivity.class);
                startActivity(intent);
            }
        });
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        Log.d(TAG, "销毁第 " + count + " 次创建的Activity,其哈希码为:" + hashCode());
        count--; //每销毁一次就 count--
    }
}

XML代码就不贴了,里面只有一个Button,下面看一下Log:

我连续两次点击了 MainActivity 的 Button ,然后又一次返回直到退出主界面。通过 Log 可以清楚看到,默认 Activity 的 Standard模式 是以栈的形式进行创建销毁的。

关于Standard模式,就写到这里,下面来写 singleTop 模式。

SingleTop

singleTop 是栈顶复用模式,先让我用不清晰的语言来解释一下:如一个 Activity 位于任务栈的栈顶,就不会再次创建该 Activity ,直接进行复用;否则,重新创建该 Activity。

为了证实,下面继续写demo。现在创建一个 MainActivity2 ,其代码如下:

public class MainActivity2 extends AppCompatActivity {
    public static final String TAG = "MainActivity2";
    public static int count1 = 0;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main2);
        count1++; //每创建一次就 count++
        Log.d(TAG, "MainActivity2 第 " + count1 + " 次被创建,其哈希码为:" + hashCode());
        findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(MainActivity2.this, MainActivity.class);
                startActivity(intent);
            }
        });
    }


    @Override
    protected void onDestroy() {
        super.onDestroy();
        Log.d(TAG, "销毁第 " + count1 + " 次创建的 MainActivity2,其哈希码为:" + hashCode());
        count1--;
    }
}

先来看看Log:

其中,MainActivity 为 singleTop模式,MainActivity2为系统默认的启动模式,我的操作是这样的:第一次点击进入 MainActivity2,然后再从 MainActivity2 进入 MainActivity。最后再依次返回。

可以看到,MainActivity 首先被创建,其次是 MainActivity2 ,再由 MainActivity2 进入 MainActivity ,MainActivity 第二次被创建。这是因为 MainActivity 虽然是 SingleTop 模式,但这个时候它已经不位于栈顶了,那就得再次被创建。

感兴趣的朋友,可以在 MainActivity 里再加一个Button,每次点击都启动自己,你就会发现 MainActivity 只创建了一次。

SingleTask

这是栈内复用模式,相对前面两个来说是比较复杂的。简单来说,该 Activity 一旦被创建而且位于任务栈中,就不会再次创建,直接复用栈内的 Activity。另外 这个模式还附加了一个 ClearTop 的效果。 什么是ClearTop呢?就是当该 Activity 不位于栈顶时,首先让位于它上面的 Activity 出栈,再把这个 Activity 置于栈顶。

测试代码很简单,和测试 SingleTop 代码差不多,就连操作都是一样的,唯一的区别就是在 AndroidManifest.xml 文件中把 MainActivity 的启动模式改为 SingleTask。见下图:

打印的Log日志如下:

MainActivity 首先被创建,在创建一个 MainActivity2,此时 MainActivity2 位于栈顶,再一次进入 MainActivity 。可以看到 MainActivity2 先出栈了,但是没有再一次 创建MainActivity,而是直接复用了原本创建的。

关于SingleTask,还有一个非常重要的属性:taskAffinity。 affinity是相关性,taskAffinity 就是任务相关性,默认情况下是包名。

launchMode 为 SingleTask 的Activity在被创建的时候会找到具有相同 taskAffinity 的任务栈,如果该任务栈存在这个 Activity 直接进行复用,如果不存在就会创建。

SingleInstance

明白了SingleTask的话,SingleInstance 非常简单,它是比 SingleTask 多了一个更加严格的限制。它要求该任务栈只能有一个 SingleInstance 模式的Activity。