1. 程式人生 > 實用技巧 >Android 活動的生命週期(三)

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 事例唯一 的活動,與其他活動存在於不同的任務棧中。如果要啟動時 它已經存在,則不再新建例項