敞开成长之旅!这是我参与「日新方案 12 月更文挑战」的第22天
首要,咱们知道,android有使命栈机制,发动使命栈的方法有xml中装备,还有便是通过intent设置flag去发动相应的activity。这儿咱们分三部分来介绍 1.xml装备的几种方法详解 2.intent flag发动的几种方法详解 3.flag 与 xml 几种方法的差异和联络
1.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);
这儿看出来了吧,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);
这儿看出来了吧,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 会销毁自身,这就行了。