1.XML配置的几种方式详解
首先,我们知道,android有任务栈机制,启动任务栈的方式有xml中配置,还有就是通过intent设置flag去启动相应的activity。这里我们分三部分来介绍 1.xml配置的几种方式详解 2.intent flag启动的几种方式详解 3.flag 与 xml 几种方式的区别和联系
Android开发者在AndroidMainifest文件中一共设计了四种启动模式,如下所示
1.1 standard
默认的启动模式,如果不指定Activity的启动模式,则使用这种方式启动Activity。这种启动模式每次都会创建新的实例,每次点击standard模式创建Activity后,都会创建新的MainActivity覆盖在原Activity上。 实际代码验证 我们实例代码验证一下,新建三个activity,xml中不配置任务栈方式(默认为标准栈),三个activity相互跳转,代码如下:
package com.itbird.task; import android.content.Intent; import android.os.Bundle; import android.util.Log; import android.view.View; import android.widget.Button; import androidx.appcompat.app.AppCompatActivity; import com.itbird.R; import com.itbird.bitmapOOM.BitmapUtils; import com.itbird.viewEvent.MyView; public class MainTestActivity extends AppCompatActivity { private static final String TAG = MainTestActivity.class.getSimpleName(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.task_test); Button button = findViewById(R.id.button); button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent(MainTestActivity.this, SecondTestActivity.class); startActivity(intent); } }); } @Override protected void onNewIntent(Intent intent) { Log.e(TAG, TAG + " onNewIntent"); super.onNewIntent(intent); } @Override protected void onDestroy() { Log.e(TAG, TAG + " onDestroy"); super.onDestroy(); } }
运行之后,跳转顺序为1-2-3-1,通过adb命令查看后台任务栈信息adb shell dumpsys activity activities | grep com.itbird
我们看到后台任务栈,的确是保持为同一个,而且activity实例一直是新建累加的。
1.2 singleTop
如果指定启动Activity为singleTop模式,那么在启动时,系统会判断当前栈顶Activity是不是要启动的Activity,如果是则不创建新的的Activity而直接引用这个Activity;如果不是则创建新的Activity。 实际代码验证 我们在第一个样例的基础代码上,把第三个activity任务栈模式改为singleTop,相同的跳转逻辑,1-2-3-3,运行查看一下任务栈信息
1.3 singleTask
singliTask模式与singleTop模式类似,只不过singleTop是坚持栈顶元素是否是需要启动的Activity,而singleTask是检测整个Activity栈中是否存在需要启动的Activity。如果存在,则将该Activity置于栈顶,并将该Activity以上的Activity都销毁。不过这里是指在同一个App中启动这个singleTask的Activity,如果是其他程序以singleTask模式来启动这个Activity,那么它将创建一个新的任务栈。不过这里有一点需要注意的是,如果启动的模式为singleTask的Activity已经在后台一个任务栈中了,那么启动后,后台的这个任务栈将一起被切换到前台。 实际代码验证 我们在第一个样例的基础代码上,把第一个activity任务栈模式改为singleTask,相同的跳转逻辑,1-2-3-1,运行查看一下任务栈信息
1.4 singleInstance
singleInstance这种模式和使用阅览器工资类似。在多个系统访问阅览器时,如果当前阅览器没有打开,则打开阅览器,否则会在当前打开的阅览器中访问。申明为singleInstance的Activity会出现在一个新的任务栈中,而且这个任务栈只会存在一个Activity。 实际代码验证 我们在第一个样例的基础代码上,把第三个activity任务栈模式改为singleInstance,相同的跳转逻辑,1-2-3-3,运行查看一下任务栈信息
2.Intent flag启动的几种方式详解
2.1 单独使用
- FLAG_ACTIVITY_NEW_TASK 加上 FLAG_ACTIVITY_NEW_TASK flag 后,启动一个 Activity 时,如果需要创建,被启动的 Activity 会在它需要的栈中创建。如 A 启动 B,B 会在 B 自己需要的栈中被创建(即 taskAffinity 指定的栈)。
我们还是以之前的三个界面的例子,三个界面的xml配置启动栈方式都为标准栈,跳转顺序为1-2-3-1,跳转过程中使用FLAG_ACTIVITY_NEW_TASK flag,代码:
Intent intent = new Intent(MainTestActivity.this, SecondTestActivity.class); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); startActivity(intent);
可以看到,在一个任务栈中,即使重新启动1,也是新建实例1,也就是说,这个Flag只是去找寻亲和属性的栈或者新建栈,并不对栈内的实例进行复用、清空等操作。这里看出来了吧,FLAG_ACTIVITY_NEW_TASK != singleTask哦,网上有很多误人子弟的文章,大家还是自己实践出真知吧
- FLAG_ACTIVITY_CLEAR_TOP 我们还是以之前的三个界面的例子,三个界面的xml配置启动栈方式都为标准栈,跳转顺序为1-2-3-1,跳转过程中使用FLAG_ACTIVITY_CLEAR_TOP flag,代码:
Intent intent = new Intent(MainTestActivity.this, SecondTestActivity.class); intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); startActivity(intent);
这时肯定有小伙伴问了,这不就和singleTask一样的效果了吗?我很确定的告诉您,不是哦~~~,clear_top如果检测到栈中有实例存在,会清空栈内包含本身的以上所有activity,我们看一下activity 1的log日志打印就知道了
所以,这里我们知道一个关键点:这里看出来了吧,FLAG_ACTIVITY_CLEAR_TOP != singleTask哦,网上有很多误人子弟的文章,大家还是自己实践出真知吧
- FLAG_ACTIVITY_SINGLE_TOP 我们还是以之前的三个界面的例子,三个界面的xml配置启动栈方式都为标准栈,跳转顺序为1-2-3-3,跳转过程中使用FLAG_ACTIVITY_SINGLE_TOP flag,代码:
Intent intent = new Intent(MainTestActivity.this, SecondTestActivity.class); intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP); startActivity(intent);
从这里可以看出,FLAG_ACTIVITY_SINGLE_TOP == singleTop哦
2.2 组合使用
针对于组合使用,我们直接说结论吧,依然是上面的例子,很好验证
- FLAG_ACTIVITY_NEW_TASK + FLAG_ACTIVITY_SINGLE_TOP activity 在前台(当前显示的栈的栈顶),不创建,它自己 onNewIntent 被调用;activity 不在前台的情形下,activity 需要的栈存在,在该栈中创建一个 activity 或将该栈移至前台(它自己 onNewIntent 被调用),activity 需要的栈不存在,创建一个它需要的栈,再创建 activity
- FLAG_ACTIVITY_NEW_TASK + FLAG_ACTIVITY_CLEAR_TOP activity 在它需要的栈里存在,它上面的 activity 会出栈,它自己 finish 后重建 activity 在它需要的栈里不存在,在它需要的栈里创建 所以此处备注:
FLAG_ACTIVITY_NEW_TASK + FLAG_ACTIVITY_CLEAR_TOP != singleTask
- FLAG_ACTIVITY_CLEAR_TOP + FLAG_ACTIVITY_SINGLE_TOP activity 在前台(当前显示的栈的栈顶),不创建,它自己 onNewIntent 被调用;activity 不在前台的情形下,activity 在它需要的栈里存在,它上面的 activity 会出栈,它自己 onNewIntent 被调用,activity 在它需要的栈里不存在,在它需要的栈里创建。 所以此处备注:
FLAG_ACTIVITY_SINGLE_TOP + FLAG_ACTIVITY_CLEAR_TOP == singleTask
3.flag 与 xml 几种方式的区别和联系
其实相关区别和联系在上面已经基本都说过了,这里用等式简单总结一下: FLAG_ACTIVITY_NEW_TASK != singleTask
FLAG_ACTIVITY_CLEAR_TOP != singleTask
FLAG_ACTIVITY_NEW_TASK + FLAG_ACTIVITY_CLEAR_TOP != singleTask
FLAG_ACTIVITY_SINGLE_TOP + FLAG_ACTIVITY_CLEAR_TOP == singleTask
FLAG_ACTIVITY_SINGLE_TOP == singleTop
当然这些结论都是基于最初的activity是标准栈的前提,如果将activity最初xml配置改为其他启动栈模式,结论可能有些就发生了一点点的改变。 我们不需要死记硬背这些知识,这些知识点最好各位结合自己的实践Demo验证一波,同时记住一点,FLAG_ACTIVITY_NEW_TASK 只是针对于栈的描述,FLAG_ACTIVITY_CLEAR_TOP 会销毁本身,这就行了。
以上就是Android 任务栈机制详解的详细内容,更多关于Android 任务栈机制的资料请关注好代码网其它相关文章!