Android 活动的生命周期(三)

活动的启动模式

1. standard  标准模式

每次启动都会打开新的实例
 

2. singleTop  栈顶唯一

如果要启动的activity处于栈顶,则不再新建实例
 

3. singleTask  栈内唯一

如果要启动的activty在Task(任务栈)中已经存在,则不再新建实例
 

4. singleInstance  事例唯一

如果要启动的activity已经存在,则不再新建实例
 
 

*演示

AndroidManifest.xml中,可以修改活动的4种启动模式

1. standard  标准模式

(1)FirstActivity.java 。按钮Button1,点击事件为 从FirstActivity跳转到FirstActivity。  打印this.toString()。

package com.androidstudy.launchmodetest;

import androidx.appcompat.app.AppCompatActivity;

import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;

public class FirstActivity extends AppCompatActivity {
    private static final String TAG = "FirstActivity";
    private Button button1;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Log.d(TAG, this.toString());
        initView();
    }
    public void initView(){
        button1 = findViewById(R.id.button1);
        button1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(FirstActivity.this,FirstActivity.class);
                startActivity(intent);
            }
        });
    }
}
FirstActivity.java

(2)运行,点击Button1,能很明显的看到,在原来的FirstActivity上,重新弹出一个FirstActivity。点击返回按钮,需要点击两次。

(3) 控制台输出如下,第一行是打开时输出的,第二行是点击按钮后输出的,很明显看到,@后的哈希码完全不同,是两个不同的实例。

结论:每次启动都会打开新的实例

2. singleTop  栈顶唯一

同上述操作,只需更改AndroidManifest.xml代码。
 

(一)Button1从FirstActivity到FirstActivity。

(1)运行,控制台输出。
 
(2)点击Button1,控制台并没有输出,证明onCreate没有再次被调用,即没有创建新的实例。
 
 

(二)Button1从FirstActivity到SecondActivity。

 创建SecondActivity,设置Button2,从SecondActivity跳转到FirstActivity。  
    修改FirstActivity,使Button1跳转到SecondActivity。
 
(1)运行,控制台输出

(2)点击Button1,跳转到了SecondActivity,此时SecondActivity位于栈顶。

 (3) 点击Button2,跳转到FirstActivity,控制台输出如下,证明创建了新实例。

结论:对于singleTop  栈顶唯一 这种启动模式,如果要启动的activity处于栈顶,则不再新建实例

3. singleTask  栈内唯一

同上述操作,只需更改AndroidManifest.xml代码。
 
(1)无论怎么点击,控制台始终只有第一次输出

(2)我们如何知道栈内的情况呢? 一个活动如果出栈的话,意味着onDestory()方法会被调用。 我们重写SecondActivityonDestory()方法和FirtstActivityonRestart()方法。

package com.androidstudy.launchmodetest;

import androidx.appcompat.app.AppCompatActivity;

import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;

public class SecondActivity extends AppCompatActivity {
    private static final String TAG = "SecondActivity";
    private Button button2;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_second);
        Log.d(TAG, this.toString());
        initView();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        Log.d(TAG, "onDestroy: ");
    }

    public void initView(){
        button2 = findViewById(R.id.button2);
        button2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(SecondActivity.this,FirstActivity.class);
                startActivity(intent);
            }
        });
    }
}
SecondActivity.java

(3)这时,我们运行,控制台输出:

(4)点击Button1,跳到SecondActivity,控制台输出:

(5) 点击Button2,返回FirstActivity,控制台输出:

(6) 再次点击Button1,控制台输出:

(5)~(6)说明SecondActivity出栈了,出栈后启动,需要新建实例。

结论:对于singleTask  栈内唯一 这种启动模式,如果要启动的activty在Task(任务栈)中已经存在,则不再新建实例
 
 
 

4. singleInstance  事例唯一

(1)为了演示的需要,singleInstance需要在SecondActivity上设置。
<activity android:name=".SecondActivity" android:launchMode="singleInstance"></activity>

(2)新建一个ThirdActivity,并且打印FirstActivity、SecondActivity、ThirdActivity的Task id。

         修改Button2,使之从SecondActivity跳转到ThirdActivity。

 protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Log.d(TAG, "Task id is" + getTaskId());
        initView();
    }
FirstActivity.java
 protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Log.d(TAG, "Task id is" + getTaskId());
        initView();
    }
SecondActivity.java

(3)运行,控制台输出:

(4)点击Button1,控制台输出:

(5)点击Button2,控制台输出:  也就是说,FirstActivity和ThirdActivity处于同一个返回栈中,而  设置了singleInstance  事例唯一启动模式  的  SecondActivity 独立的存在于一个任务栈中。

(6)这时,在ThirdActivity中点击返回按钮,发现回到了FirstActivity,而不是SecondActivity。

(7)再次点击Button1,回到了SecondActivity,控制台输出:

结论:启动模式为 singleInstance  事例唯一 的活动,与其他活动存在于不同的任务栈中。如果要启动时 它已经存在,则不再新建实例

 
原文地址:https://www.cnblogs.com/Master-Sun/p/14246518.html