之前写的Android-Activity启动模式(launchMode),Android-Activity启动模式-应用场景,讲解的都是在AndroidManifest.xml配置launchMode="四种启动模式"
Activity启动模式分为四种:
如果不配置:launchMode,默认就是:standard 标准的
standard 标准的
singleTop 独占顶端
singleTask 单任务
singleInstance 单实例
standard 标准的,特点是:启动一个Activity就进栈一个Activity,启动六个Activity就进栈六个Activity
在LoginActivity --> intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); // 该Flag相当于Activity启动模式中的standard。
注意:⚠️ intent.addFlags(Activity模式); 为给指定调整的Activity设置此模式
/** * 启动 NewActivity * @param view */ public void startNewActivity(View view) { Intent intent = new Intent(this, NewActivity.class); // intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); // 该Flag相当于Activity启动模式中的singleTask intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); // 该Flag相当于Activity启动模式中的standard。 // intent.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY); // 以该旗标启动的Activity不会保留在Activity栈中 startActivity(intent); }
singleTop 独占顶端,特点是LoginActivity在顶端的时候,启动LoginActivity会自动重用LoginActivity,不会进栈
在LoginActivity --> intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP); // Flag相当于Activity加载模式中的singleTop模式
注意:⚠️ intent.addFlags(Activity模式); 为给指定调整的Activity设置此模式
/** * 启动自己 * @param view */ public void startThis(View view) { Intent intent = new Intent(this, LoginActivity.class); intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP); // Flag相当于Activity加载模式中的singleTop模式 startActivity(intent); }
LoginActivity intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP); :
(当LoginActivity在顶端,无论点击启动自己多少此都不会进栈 而是重用)
(当点击返回back键的时候,任务栈里面只有一个Activity的引用)
01-02 20:46:06.493 2196-2196/liudeli.activity D/launchMode: onNewIntent LoginActivity被重用了
01-02 20:46:07.244 2196-2196/liudeli.activity D/launchMode: onNewIntent LoginActivity被重用了
01-02 20:46:07.960 2196-2196/liudeli.activity D/launchMode: onNewIntent LoginActivity被重用了
01-02 20:46:08.545 2196-2196/liudeli.activity D/launchMode: onNewIntent LoginActivity被重用了
01-02 20:46:08.677 2196-2196/liudeli.activity D/launchMode: onNewIntent LoginActivity被重用了
01-02 20:46:08.811 2196-2196/liudeli.activity D/launchMode: onNewIntent LoginActivity被重用了
01-02 20:46:08.947 2196-2196/liudeli.activity D/launchMode: onNewIntent LoginActivity被重用了
01-02 20:46:09.079 2196-2196/liudeli.activity D/launchMode: onNewIntent LoginActivity被重用了
01-02 20:46:09.218 2196-2196/liudeli.activity D/launchMode: onNewIntent LoginActivity被重用了
01-02 20:46:09.364 2196-2196/liudeli.activity D/launchMode: onNewIntent LoginActivity被重用了
01-02 20:46:09.494 2196-2196/liudeli.activity D/launchMode: onNewIntent LoginActivity被重用了
01-02 20:46:09.628 2196-2196/liudeli.activity D/launchMode: onNewIntent LoginActivity被重用了
01-02 20:46:09.761 2196-2196/liudeli.activity D/launchMode: onNewIntent LoginActivity被重用了
01-02 20:46:09.914 2196-2196/liudeli.activity D/launchMode: onNewIntent LoginActivity被重用了
singleTask 单任务,特点是单任务,不会有两个NewActivity引用,NewActivity一旦进栈 就不会再次进栈了
在LoginActivity --> intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); // 该Flag相当于Activity启动模式中的singleTask
注意:⚠️ intent.addFlags(Activity模式); 为给指定调整的Activity设置此模式
/** * 启动 NewActivity * @param view */ public void startNewActivity(View view) { Intent intent = new Intent(this, NewActivity.class); intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); // 该Flag相当于Activity启动模式中的singleTask // intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); // 该Flag相当于Activity启动模式中的standard。 // intent.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY); // 以该旗标启动的Activity不会保留在Activity栈中 startActivity(intent); }
例如:NewActivity设置了 singleTask启动模式:当启动过一次NewActivity,再次启动NewActivity的时候,会自动从栈底往上找,一旦找到NewActivity(一直杀到最顶端)
01-02 21:16:54.414 3192-3192/liudeli.activity D/launchMode: LoginActivity 任务栈ID: 89
01-02 21:17:12.164 3192-3192/liudeli.activity D/launchMode: NewActivity 任务栈ID: 89
01-02 21:17:15.201 3192-3192/liudeli.activity D/launchMode: LoginActivity 任务栈ID: 89
01-02 21:17:17.884 3192-3192/liudeli.activity D/launchMode: LoginActivity 任务栈ID: 89
01-02 21:17:18.698 3192-3192/liudeli.activity D/launchMode: LoginActivity 任务栈ID: 89
01-02 21:17:21.416 3192-3192/liudeli.activity D/launchMode: NewActivity 任务栈ID: 89
在LoginActivity --> intent.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY); // 以该旗标启动的Activity不会保留在Activity栈中
注意:⚠️ intent.addFlags(Activity模式); 为给指定调整的Activity设置此模式
如果不给 NewActivity 添加intent.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);,任务栈里面会有四个Activity引用
目前给 NewActivity 添加intent.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);,任务栈里面会有三个Activity引用,NewActivity不会重复的保存到任务栈中
完整代码:
AndroidManifest.xml
<activity android:name=".launch_mode.LoginActivity"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity android:name=".launch_mode.NewActivity" />
LoginActivity
package liudeli.activity.launch_mode; import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.util.Log; import android.view.View; import liudeli.activity.R; public class LoginActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_login); /** * 每款应用程序启动后,会默认有一个任务栈(用于存放Activity的引用) * 任务栈有栈ID,随着应用程序的启动 栈ID是累加的 */ int taskId = getTaskId(); Log.d("launchMode", "LoginActivity 任务栈ID: " + taskId); } /** * 启动 NewActivity * @param view */ public void startNewActivity(View view) { Intent intent = new Intent(this, NewActivity.class); // intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); // 该Flag相当于Activity启动模式中的singleTask // intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); // 该Flag相当于Activity启动模式中的standard。 intent.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY); // 以该旗标启动的Activity不会保留在Activity栈中 startActivity(intent); } /** * 启动自己 * @param view */ public void startThis(View view) { Intent intent = new Intent(this, LoginActivity.class); // intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP); // Flag相当于Activity加载模式中的singleTop模式 startActivity(intent); } /** * 当Activity被重用了就会调用此方法 * @param intent */ @Override protected void onNewIntent(Intent intent) { super.onNewIntent(intent); Log.d("launchMode", "onNewIntent LoginActivity被重用了"); } }
activity_login.xml
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="启动新的Activity" android:onClick="startNewActivity" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="启动自己" android:onClick="startThis" android:layout_alignParentRight="true" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="LoginActivity 永远都是标准模式" android:layout_centerInParent="true" android:textSize="20sp" /> </RelativeLayout>
NewActivity
package liudeli.activity.launch_mode; import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.util.Log; import android.view.View; import liudeli.activity.R; public class NewActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_new); /** * 每款应用程序启动后,会默认有一个任务栈(用于存放Activity的引用) * 任务栈有栈ID,随着应用程序的启动 栈ID是累加的 */ int taskId = getTaskId(); Log.d("launchMode", "NewActivity 任务栈ID: " + taskId); } /** * 启动登录Activity * @param view */ public void startLoginActivity(View view) { startActivity(new Intent(this, LoginActivity.class)); } /** * 启动自己 * @param view */ public void startThis(View view) { startActivity(new Intent(this, NewActivity.class)); } /** * 当Activity被重用了就会调用此方法 * @param intent */ @Override protected void onNewIntent(Intent intent) { super.onNewIntent(intent); Log.d("launchMode", "onNewIntent NewActivity被重用了"); } }
activity_new.xml
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="启动登录Activity" android:onClick="startLoginActivity" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:text="启动自己" android:onClick="startThis" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="newActivity" android:layout_centerInParent="true" android:textSize="20sp" android:textColor="#f00" /> </RelativeLayout>