大家好,又见面了,我是你们的朋友全栈君。
介绍 Android 启动模式之前,先介绍两个概念task和taskAffinity
4种启动模式
4.singleInstance:单实例模式。这个是 singleTask 模式的加强版,它除了具有 singleTask 模式的所有特性外,它还有一点独特的特性,那就是此模式的 Activity 只能单独地位于一个任务栈,不与其他 Activity 共存于同一个任务栈。从这个 Activity 启动的任何其他Activity都会放到其他的任务栈。
还有一点:
无论 Activity 是在新任务栈中启动还是在相同的任务栈中启动,“返回”按钮始终会将用户带到上一个 Activity。但是,如果启动指定了 singleTask启动模式的 Activity,同时如果 后台 任务栈中存在该 Activity 的实例,则将整个任务栈内的 Activity 带到前台。此时,当前任务栈 现在包括在堆栈顶部提出的任务中的所有活动。如果不理解,下图说明这种情况。
通过上面我们了解了Activity的几种启动模式,接下来我们看看 SingleTask和 Intent.FLAG_ACTIVITY_CLEAR_TOP的区别:
singleTask:栈内复用模式。是一种单实例模式,在这种模式下,如果该Activity在栈中存在,那么多次启动此Activity都不会重新创建实例,而是销毁在它之上的所有Activity(不包括它本身),复用该Activity并调用它的onNewIntent方法,如果该Activity不存在,则创建该Activity并将其入栈到该Activity所需的任务栈中。
Intent.FLAG_ACTIVITY_CLEAR_TOP:销毁目标Activity和它之上的所有Activity,重新创建目标Activity,不会调用onNewIntent方法。
Intent.FLAG_ACTIVITY_SINGLE_TOP :当该activity处于栈顶时,可以复用,直接onNewIntent。
接下来我们看demo:
在Manifest文件中我们将MainActivity指定为singleTask,
<activity
android:name=".MainActivity"
android:configChanges="orientation"
android:launchMode="singleTask">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".SecondActivity" />
<activity android:name=".ThirdActivity"></activity>
在每个Activity的onCreate方法中打印栈信息:
private String getTaskInfo(){
StringBuilder builder = new StringBuilder();
ActivityManager am = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
List<ActivityManager.RunningTaskInfo> taskInfos = am.getRunningTasks(10);
for (ActivityManager.RunningTaskInfo task: taskInfos){
builder.append("id= "+task.id+"\n");
builder.append("description= "+task.description+"\n");
builder.append("numActivityes= "+task.numActivities+"\n");
builder.append("topActivity= "+task.topActivity+"\n");
builder.append("baseActivity= "+task.baseActivity.toString()+"\n");
}
return builder.toString();
}
MainActivity中设置一个Button启动SecondActivity:
Intent intent =new Intent(MainActivity.this,SecondActivity.class);
startActivity(intent);
SecondActivity中设置一个Button启动ThirdActivity:
Intent intent = new Intent(SecondActivity.this,ThirdActivity.class);
startActivity(intent);
SecondActivity中设置一个Button启动MainActivity,并传递消息:
Intent intent = new Intent(ThirdActivity.this,MainActivity.class);
startActivity(intent);
MainActivity的onNewIntent方法同样打印栈信息:
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
String taskInfo = getTaskInfo();
Log.e(TAG, "onNewIntent: "+taskInfo);
}
启动app,看打印出来什么东西
首先启动的是MainActivity,
MainActivity: onCreate: id= 1568
description= null
numActivityes= 1
topActivity= ComponentInfo{com.example.hp.testtext/com.example.hp.testtext.MainActivity}
baseActivity= ComponentInfo{com.example.hp.testtext/com.example.hp.testtext.MainActivity}
id= 1559
description= null
numActivityes= 1
topActivity= ComponentInfo{com.google.android.apps.nexuslauncher/com.google.android.apps.nexuslauncher.NexusLauncherActivity}
baseActivity= ComponentInfo{com.google.android.apps.nexuslauncher/com.google.android.apps.nexuslauncher.NexusLauncherActivity}
可以看到MainActivity所在栈中Activity的数目numActivityes等于1,topActivity和baseActivity表示栈顶和栈底的Activity,
接下来启动SecondActivity,
SecondActivity: onCreate: id= 1568
description= null
numActivityes= 2
topActivity= ComponentInfo{com.example.hp.testtext/com.example.hp.testtext.SecondActivity}
baseActivity= ComponentInfo{com.example.hp.testtext/com.example.hp.testtext.MainActivity}
id= 1559
description= null
numActivityes= 1
topActivity= ComponentInfo{com.google.android.apps.nexuslauncher/com.google.android.apps.nexuslauncher.NexusLauncherActivity}
baseActivity= ComponentInfo{com.google.android.apps.nexuslauncher/com.google.android.apps.nexuslauncher.NexusLauncherActivity}
可以看到栈中的Activity变为2
接下来启动ThirdActivity,
ThirdActivity: onCreate: id= 1568
description= null
numActivityes= 3
topActivity= ComponentInfo{com.example.hp.testtext/com.example.hp.testtext.ThirdActivity}
baseActivity= ComponentInfo{com.example.hp.testtext/com.example.hp.testtext.MainActivity}
id= 1559
description= null
numActivityes= 1
topActivity= ComponentInfo{com.google.android.apps.nexuslauncher/com.google.android.apps.nexuslauncher.NexusLauncherActivity}
baseActivity= ComponentInfo{com.google.android.apps.nexuslauncher/com.google.android.apps.nexuslauncher.NexusLauncherActivity}
栈中的Activity变为3,
接着我们从ThirdActivity启动MainActivity,
MainActivity: onNewIntent: id= 1569
description= null
numActivityes= 1
topActivity= ComponentInfo{com.example.hp.testtext/com.example.hp.testtext.MainActivity}
baseActivity= ComponentInfo{com.example.hp.testtext/com.example.hp.testtext.MainActivity}
id= 1559
description= null
numActivityes= 1
topActivity= ComponentInfo{com.google.android.apps.nexuslauncher/com.google.android.apps.nexuslauncher.NexusLauncherActivity}
baseActivity= ComponentInfo{com.google.android.apps.nexuslauncher/com.google.android.apps.nexuslauncher.NexusLauncherActivity}
我们发现这里只执行了onNewIntent方法,没有执行onCreate方法,说明服用了MainActivity,并且栈中只剩MainActivity,其他两个Activity都被销毁了。
接下来我们把MainActivity的singleTask启动模式去掉(默认启动模式),并且ThirdActivity中启动MainActivity的代码如下:
Intent intent = new Intent(ThirdActivity.this,MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
前面的步骤不变,当我们从ThirdActivity启动MainActivity时,打印的信息如下:
MainActivity: onCreate: id= 1570
description= null
numActivityes= 1
topActivity= ComponentInfo{com.example.hp.testtext/com.example.hp.testtext.MainActivity}
baseActivity= ComponentInfo{com.example.hp.testtext/com.example.hp.testtext.MainActivity}
id= 1559
description= null
numActivityes= 1
topActivity= ComponentInfo{com.google.android.apps.nexuslauncher/com.google.android.apps.nexuslauncher.NexusLauncherActivity}
baseActivity= ComponentInfo{com.google.android.apps.nexuslauncher/com.google.android.apps.nexuslauncher.NexusLauncherActivity}
执行的是onCreate方法,说明MainActivity被重新创建了,同时其他两个Activity也是被销毁。
我们把ThirdActivity中的代码修改一下:
Intent intent = new Intent(ThirdActivity.this,MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP|Intent.FLAG_ACTIVITY_SINGLE_TOP);
startActivity(intent);
打印结果如下:
MainActivity: onNewIntent: id= 1571
description= null
numActivityes= 1
topActivity= ComponentInfo{com.example.hp.testtext/com.example.hp.testtext.MainActivity}
baseActivity= ComponentInfo{com.example.hp.testtext/com.example.hp.testtext.MainActivity}
id= 1559
description= null
numActivityes= 1
topActivity= ComponentInfo{com.google.android.apps.nexuslauncher/com.google.android.apps.nexuslauncher.NexusLauncherActivity}
baseActivity= ComponentInfo{com.google.android.apps.nexuslauncher/com.google.android.apps.nexuslauncher.NexusLauncherActivity}
可以看到,使用Intent.FLAG_ACTIVITY_CLEAR_TOP + Intent.FLAG_ACTIVITY_SINGLE_TOP时调用了onNewIntent方法,复用了MainActivity,说明他们可以实现和singleTask一样的效果
singleTask会销毁目标Activity之上的Activity并复用已经存在的目标Activity(调用onNewIntent),但Intent.FLAG_ACTIVITY_CLEAR_TOP会连同目标Activity一起销毁,然后重新创建目标Activity。
singleTask是写死在Manifest文件中的,如果觉得太笨重,可以同时使用Intent.FLAG_ACTIVITY_CLEAR_TOP + Intent.FLAG_ACTIVITY_SINGLE_TOP达到和singleTask一样的效果。
如果觉得不错顺手点个赞吧!!!
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/160736.html原文链接:https://javaforall.cn