
前言
任务栈
是一种后进先出的结构。位于栈顶的Activity处于焦点状态,当按下back按钮的时候,栈内的Activity会一个一个的出栈,并且调用其onDestory()方法。如果栈内没有Activity,那么系统就会回收这个栈,每个APP默认只有一个栈,以APP的包名来命名。
为什么要引入任务栈的概念?
Windows下 可以通过点击任务栏 切换任务
Android下 长按小房子 切换任务
为了记录用户开启了那些Activity
,记录这些Activity
开启的先后顺序,Google引入任务栈(Task stack)概念
,帮助维护好的用户体验。
-
Stack(栈)
栈(stack)
在计算机科学中是限定仅在表尾进行插入或删除操作的线性表。栈是一种数据结构,它按照后进先出的原则存储数据,先进入的数据被压入栈底,最后的数据在栈顶,需要读数据的时候从栈顶开始弹出数据。栈是只能在某一端插入和删除的特殊线性表。用桶堆积物品,先堆进来的压在底下,随后一件一件往上堆。取走时,只能从上面一件一件取。读和取都在顶部进行,底部一般是不动的。栈就是一种类似桶堆积物品的数据结构,进行删除和插入的一端称栈顶,另一端称栈底。插入一般称为进栈,删除则称为退栈。 栈也称为后进先出表
-
Heap(堆)
堆(heap)
又被为优先队列(priority queue)。尽管名为优先队列,但堆并不是队列。回忆一下,在队列中,我们可以进行的限定操作是dequeue和enqueue。dequeue是按照进入队列的先后顺序来取出元素。而在堆中,我们不是按照元素进入队列的先后顺序取出元素的,而是按照元素的优先级取出元素.
堆栈缓存方式
栈(stack)
使用的是一级缓存, 他们通常都是被调用时处于存储空间中,调用完毕立即释放。
堆(heap)
则是存放在二级缓存中,生命周期由虚拟机的垃圾回收算法来决定(并不是一旦成为孤儿对象就能被回收)。所以调用这些对象的速度要相对来得低一些
Activity 启动模式
Standard (标准模式)
默认标准的启动模式, 每次startActivity都是创建一个新的activity的实例。适用于绝大大数情况。
SingleTop (栈顶复用)
栈顶复用,如果要开启的activity在任务栈的顶部已经存在,就不会创建新的实例,而是调用 onNewIntent()
方法。
SingleTask (栈内复用)
Activity只会在任务栈里面存在一个实例。如果要激活的activity,在
任务栈里面已经存在,就不会创建新的activity,而是复用这个已经存在的activity,调用 onNewIntent()
方法,并且清空这个activity任务栈上面所有的activity。
SingleInstance(单例模式)
单一实例,整个手机操作系统里面只有一个实例存在。不同的应用去打开这个activity共享公用的同一个activity。他会运行在自己单独,独立的任务栈里面,并且任务栈里面只有他一个实例存在。
Activity 启动模式设置:
- 在AndroidManifest.xml中对指定Activity配置:
android:launchMode="singleInstance" - 代码动态设置
Activity压栈处理:(附完整代码)
/**
* description: 封装Activity相关工具类
* autour: Knight
* new date: 2018/6/12 on 16:26
* e-mail: 37442216knight@gmail.com
* update: 2018/6/12 on 16:26
* version: v 1.0
*/
public class RxActivityTool {
private static Stack<Activity> activityStack;
/**
* 添加Activity 到栈
*
* @param activity
*/
public static void addActivity(Activity activity) {
if (activityStack == null) {
activityStack = new Stack<>();
}
activityStack.add(activity);
}
/**
* 获取当前的Activity(堆栈中最后一个压入的)
*/
public static Activity currentActivity() {
Activity activity = activityStack.lastElement();
return activity;
}
/**
* 结束当前Activity(堆栈中最后一个压入的)
*/
public static void finishActivity() {
Activity activity = activityStack.lastElement();
activity.finish();
}
/**
* 结束指定的Activity
*
* @param activity
*/
public static void finishActivity(Activity activity) {
if (activity != null) {
activityStack.remove(activity);
activity.finish();
activity = null;
}
}
/**
* 结束指定类名的Activity
*/
public static void finishActivity(Class<?> cls) {
for (Activity activity : activityStack) {
if (activity.getClass().equals(cls)) {
finishActivity(activity);
}
}
}
/**
* 结束所有的Activity
*/
public static void finishAllActivity() {
int size = activityStack.size();
for (int i = 0; i < size; i++) {
if (null != activityStack.get(i)) {
activityStack.get(i).finish();
}
}
activityStack.clear();
}
public static void AppExit(Context context) {
try {
finishAllActivity();
ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
activityManager.restartPackage(context.getPackageName());
System.exit(0);
} catch (Exception e) {
e.printStackTrace();
}
}
public static Stack<Activity> getActivityStack() {
return activityStack;
}
/**
* 判断是否存在指定Activity
*
* @param context 上下文
* @param packageName 包名
* @param className activity全路径类名
* @return {@code true}: 是<br>{@code false}: 否
*/
public static boolean isExistActivity(Context context, String packageName, String className) {
Intent intent = new Intent();
intent.setClassName(packageName, className);
return !(context.getPackageManager().resolveActivity(intent, 0) == null ||
intent.resolveActivity(context.getPackageManager()) == null ||
context.getPackageManager().queryIntentActivities(intent, 0).size() == 0);
}
/**
* 打开指定的Activity
*
* @param context 上下文
* @param packageName 包名
* @param className 全类名
*/
public static void launchActivity(Context context, String packageName, String className) {
launchActivity(context, packageName, className, null);
}
/**
* 打开指定的Activity
*
* @param context 上下文
* @param packageName 包名
* @param className 全类名
* @param bundle bundle
*/
public static void launchActivity(Context context, String packageName, String className, Bundle bundle) {
context.startActivity(RxIntentTool.getComponentNameIntent(packageName, className, bundle));
}
/**
* 要求最低API为11
* Activity 跳转
* 跳转后Finish之前所有的Activity
*
* @param context
* @param goal
*/
public static void startActivityAndFinishAll(Context context, Class<?> goal, Bundle bundle) {
Intent intent = new Intent(context, goal);
intent.putExtras(bundle);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
context.startActivity(intent);
((Activity) context).finish();
}
/**
* 要求最低API为11
* Activity 跳转
* 跳转后Finish之前所有的Activity
*
* @param context
* @param goal
*/
public static void startActivityAndFinishAll(Context context, Class<?> goal) {
Intent intent = new Intent(context, goal);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
context.startActivity(intent);
((Activity) context).finish();
}
/**
* Activity 跳转
*
* @param context
* @param goal
*/
public static void startActivityAndFinish(Context context, Class<?> goal, Bundle bundle) {
Intent intent = new Intent(context, goal);
intent.putExtras(bundle);
context.startActivity(intent);
((Activity) context).finish();
}
/**
* Activity 跳转
*
* @param context
* @param goal
*/
public static void startActivityAndFinish(Context context, Class<?> goal) {
Intent intent = new Intent(context, goal);
context.startActivity(intent);
((Activity) context).finish();
}
/**
* Activity 跳转
*
* @param context
* @param goal
*/
public static void startActivity(Context context, Class<?> goal) {
Intent intent = new Intent(context, goal);
context.startActivity(intent);
}
/**
* Activity 跳转
*
* @param context
* @param goal
*/
public static void startActivity(Context context, Class<?> goal, Bundle bundle) {
Intent intent = new Intent(context, goal);
intent.putExtras(bundle);
context.startActivity(intent);
}
public static void startActivityForResult(Activity context, Class<?> goal, int requestCode) {
Intent intent = new Intent(context, goal);
context.startActivityForResult(intent, requestCode);
}
public static void startActivityForResult(Activity context, Class<?> goal, Bundle bundle, int requestCode) {
Intent intent = new Intent(context, goal);
intent.putExtras(bundle);
context.startActivityForResult(intent, requestCode);
}
/**
* 获取launcher activity
*
* @param context 上下文
* @param packageName 包名
* @return launcher activity
*/
public static String getLauncherActivity(Context context, String packageName) {
Intent intent = new Intent(Intent.ACTION_MAIN, null);
intent.addCategory(Intent.CATEGORY_LAUNCHER);
PackageManager pm = context.getPackageManager();
List<ResolveInfo> infos = pm.queryIntentActivities(intent, 0);
for (ResolveInfo info : infos) {
if (info.activityInfo.packageName.equals(packageName)) {
return info.activityInfo.name;
}
}
return "no " + packageName;
}
总结:
开发过程中,Activity启动模式
,以及对Activity 的压栈是每天都能遇到了,合理的处理堆栈可以提高性能和代码的整洁性。
网友评论