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 { privateFirstActivity.javastatic 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); } }); } }
(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()方法會被呼叫。 我們重寫SecondActivity的onDestory()方法和FirtstActivity的onRestart()方法。
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 事例唯一 的活動,與其他活動存在於不同的任務棧中。如果要啟動時 它已經存在,則不再新建例項