【我的Android开发】AMS中Activity栈管理
创始人
2024-05-29 16:03:09
0

概述

Activity栈管理是AMS的另一个重要功能,栈管理又和Activity的启动模式和startActivity时所设置的Flag息息相关,Activity栈管理的主要处理逻辑是在ActivityStarter#startActivityUnchecked方法中,本文也会围绕着这个方法进进出出,反复摩擦,直到脑海中都是它的形状。goolge的工程师起名还是很讲究的,为什么要带Unchecked呢? Unchecked-不确定,是因为在执行这个方法时,我要启动哪个Activity还没决定呢,具体为什么,我想看过这篇文章你就明白了。

Activity栈管理相关类

ActivityStackSupervisor

Activity栈的管理人

ActivityDisplay

表示一个屏幕,Android支持三种屏幕,主屏幕,外接屏幕,虚拟屏幕(投屏)【这个介绍是从其他地方看来的,并不确定】。一般在手机上只有主屏幕,此时ActivityStackSupervisor与ActivityDisplay都是系统唯一的

TaskRecord

是ActivityTask的记录,TaskRecord是Activity栈的重要管理单元。形象一点理解,记得启动模式的 singleTask 吧?意思就是让这个Activity在单独的TaskRecord中启动。“Task":任务。

ActivityRecord

记录着每个Activity的信息,ActivityRecord和Activity一一对应。

ActivityStack

是ActivityRecord和TaskRecord两者的统一上司,记录着ActivityRecord和TaskRecord的状态。

如果在只有主屏幕的设备上,他们之间的关系大概是这样子的:

请添加图片描述

可以理解为一个屏幕上,可能会有很多个APP进程,每个APP进程对应一个ActivityStack,也就是activity栈,其中由于Activity的启动模式不同,又形成了若干个TaskRecord,其中包含着若干个ActivityRecord。

Activity 的四种启动模式,以及启动标识符

Standard

标准启动模式,启动Activity的时候向发起人的Task顶直接添加即可,返回时依次退出。

SingleTop

栈顶唯一,如果栈顶Activity不是要启动的Activity,则会创建一个新的Activity实例,但如果栈顶Activity就是我们要启动的Activity,就只会调用onNewIntent,而不去再重新创建一个实例。相比Standard,Standard不论如何,都会创建一个新的实例。

SingleTask

栈内唯一。如果发起启动的ActivityRecord所在的TaskRecord中,有要启动的Activity对应的ActivityRecord,则首先将TaskRecord中,目标Activity之上的所有ActivityRecord全都弹出,然后将所在TaskRecord变为ActivityStack的栈顶。

如果发起启动的ActivityRecord所在的TaskRecord中,没有要启动的Activity对应的ActivityRecord,则会在栈顶新建一个TaskRecord,并向其中实例化一个需要启动的Activity对应的ActivityRecord。

SingleInstance

独占一个TaskRecord。启动时,在ActivityStack中查找是否有相同的Activity,如果有,则用这个独占TaskRecord的ActivityRecord对应的Activity。否则新建一个TaskRecord,里面只有它存在。由singleInstance发起的启动,不论是谁,都会在另一个task中启动。

代码实现

通过对"android.app.ActivityThread"进行反射。获取android系统的activity栈

遍历activity栈能够得到当前应用中的全部存活的activity。

        Log.e("Baseactivty", this.getClass().getName() +":oncreate");Class activityThreadClass = null;try {activityThreadClass = Class.forName("android.app.ActivityThread");Object activityThread = activityThreadClass.getMethod("currentActivityThread").invoke(null);Field activitiesField = activityThreadClass.getDeclaredField("mActivities");activitiesField.setAccessible(true);Map activities = (Map) activitiesField.get(activityThread);int i = 0;for (Object activityRecord : activities.values()) {Class activityRecordClass = activityRecord.getClass();Field activityField = activityRecordClass.getDeclaredField("activity");activityField.setAccessible(true);Activity activity = (Activity) activityField.get(activityRecord);Log.e("activityThreadClass", "index:" + i + ",sum:" + activities.size()+ ", class name:" + activity.getClass().getName());i++;}} catch (ClassNotFoundException e) {e.printStackTrace();} catch (NoSuchMethodException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();} catch (Exception e) {e.printStackTrace();}

当你在Activity的oncreate中调用上述方法时。你会发现activity列表activities中没有当前的activity,这是由于当前activity还没有被增加栈中。可是onResume中调用上面的函数。就发现当前activity已经被增加栈中。

2.2 重写Instrumentation

监听activity的声明周期。现实自己想要的操作。

首先"绕庄"操作,即在当前project的src文件夹以下新建anroid.app包,然后声明ActivityThread、Instrumentation、LoadedApk三个文件。

ActivityThread类

package android.app;import android.content.pm.ApplicationInfo;public final class ActivityThread {/*** NOTICE: 必须在UI线程调用本方法,否则返回NULL** @return*/public static ActivityThread currentActivityThread() {return null;}public final LoadedApk getPackageInfoNoCheck(ApplicationInfo ai) {return null;}
}

Instrumentation类

package android.app;import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.ActivityInfo;
import android.os.Bundle;
import android.os.IBinder;
import android.view.KeyEvent;
import android.view.MotionEvent;public class Instrumentation {public void onCreate(Bundle arguments) {}public void start() {}public void onStart() {}public boolean onException(Object obj, Throwable e) {return false;}public void sendStatus(int resultCode, Bundle results) {}public void finish(int resultCode, Bundle results) {}public void setAutomaticPerformanceSnapshots() {}public void startPerformanceSnapshot() {}public void endPerformanceSnapshot() {}public void onDestroy() {}public Context getContext() {return null;}public ComponentName getComponentName() {return null;}public Context getTargetContext() {return null;}public boolean isProfiling() {return false;}public void startProfiling() {}public void stopProfiling() {}public void setInTouchMode(boolean inTouch) {}public void waitForIdle(Runnable recipient) {}public void waitForIdleSync() {}public void runOnMainSync(Runnable runner) {}public Activity startActivitySync(Intent intent) {return null;}public void addMonitor(ActivityMonitor monitor) {}public Instrumentation.ActivityMonitor addMonitor(IntentFilter filter, ActivityResult result, boolean block) {return null;}public ActivityMonitor addMonitor(String cls, ActivityResult result, boolean block) {return null;}public boolean checkMonitorHit(ActivityMonitor monitor, int minHits) {return false;}public Activity waitForMonitor(ActivityMonitor monitor) {return null;}public Activity waitForMonitorWithTimeout(ActivityMonitor monitor, long timeOut) {return null;}public void removeMonitor(ActivityMonitor monitor) {}public boolean invokeMenuActionSync(Activity targetActivity, int requestCode, int flag) {return false;}public boolean invokeContextMenuAction(Activity targetActivity, int requestCode, int flag) {return false;}public void sendStringSync(String text) {}public void sendKeySync(KeyEvent event) {}public void sendKeyDownUpSync(int key) {}public void sendCharacterSync(int keyCode) {}public void sendPointerSync(MotionEvent event) {}public void sendTrackballEventSync(MotionEvent event) {}public Application newApplication(ClassLoader cl, String className, Context who) throws InstantiationException, IllegalAccessException, ClassNotFoundException {return null;}public void callApplicationOnCreate(Application app) {}public Activity newActivity(Class clazz, Context who, IBinder token, Application application, Intent intent, ActivityInfo info, CharSequence title, Activity parent, String id, Object lastNonConfigurationInstance) throws InstantiationException, IllegalAccessException {return null;}public Activity newActivity(ClassLoader cl, String className, Intent intent) throws InstantiationException, IllegalAccessException, ClassNotFoundException {return null;}public void callActivityOnCreate(Activity target, Bundle icicle) {}public void callActivityOnDestroy(Activity target) {}public void callActivityOnRestoreInstanceState(Activity target, Bundle savedInstanceState) {}public void callActivityOnPostCreate(Activity target, Bundle icicle) {}public void callActivityOnNewIntent(Activity target, Intent intent) {}public void callActivityOnStart(Activity target) {}public void callActivityOnRestart(Activity target) {}public void callActivityOnResume(Activity target) {}public void callActivityOnStop(Activity target) {}public void callActivityOnSaveInstanceState(Activity target, Bundle outState) {}public void callActivityOnPause(Activity target) {}public void callActivityOnUserLeaving(Activity target) {}public void startAllocCounting() {}public void stopAllocCounting() {}public Bundle getAllocCounts() {return null;}public Bundle getBinderCounts() {return null;}public UiAutomation getUiAutomation() {return null;}public ActivityResult execStartActivity(final Context who, final IBinder contextThread, final IBinder token, final Activity target, final Intent intent, final int requestCode) {return null;}public ActivityResult execStartActivity(final Context who, final IBinder contextThread, final IBinder token, final Activity target, final Intent intent, final int requestCode, final Bundle options) {return null;}public ActivityResult execStartActivity(final Context who, final IBinder contextThread, final IBinder token, final Fragment fragment, final Intent intent, final int requestCode) {return null;}public ActivityResult execStartActivity(final Context who, final IBinder contextThread, final IBinder token, final Fragment fragment, final Intent intent, final int requestCode, final Bundle options) {return null;}protected static final class ActivityMonitor {}public static final class ActivityResult {}}

LoadedApk类

package android.app;public class LoadedApk {public Application makeApplication(boolean forceDefaultAppClass,Instrumentation instrumentation) {return null;}public ClassLoader getClassLoader() {return null;}
}

首先"绕庄"的目的是为绕过编译过程,Instrumentation属于内核实现类型,不能直接使用,否则会编译出错。

以下是一个反射的工具类,有lody大神设计

NULL类

/*** 用来表示null的类.**/
public class NULL {
}

Reflect类

import java.lang.reflect.AccessibleObject;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Member;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.Proxy;
import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.Map;import android.annotation.SuppressLint;/*** 一个拥有流畅特性(Fluent-API)的反射工具类,* 使用起来就像直接调用一样流畅易懂.**/
@SuppressLint("DefaultLocale")
public class Reflect {private final Object object;private final boolean isClass;private Reflect(Class type) {this.object = type;this.isClass = true;}private Reflect(Object object) {this.object = object;this.isClass = false;}/*** 依据指定的类名构建反射工具类** @param name 类的全名* @return 反射工具类* @throws 假设反射出现意外* @see #on(Class)*/public static Reflect on(String name) throws ReflectException {return on(forName(name));}/*** 从指定的类载入起寻找类,并构建反射工具类** @param name        类的全名* @param classLoader 须要构建工具类的类的类载入器*                    loaded.* @return 反射工具类* @throws ReflectException 假设反射出现意外* @see #on(Class)*/public static Reflect on(String name, ClassLoader classLoader) throws ReflectException {return on(forName(name, classLoader));}/*** 依据指定的类构建反射工具类* 

* 当你须要訪问静态字段的时候本方法适合你,* 你还能够通过调用 {@link #create(Object...)} 创建一个对象.** @param clazz 须要构建反射工具类的类* @return 反射工具类*/public static Reflect on(Class clazz) {return new Reflect(clazz);}// ---------------------------------------------------------------------// 构造器// ---------------------------------------------------------------------/*** Wrap an object.*

* Use this when you want to access instance fields and methods on any* {@link Object}** @param object The object to be wrapped* @return A wrapped object, to be used for further reflection.*/public static Reflect on(Object object) {return new Reflect(object);}/*** 让一个{@link AccessibleObject}可訪问.** @param accessible* @param * @return*/public static T accessible(T accessible) {if (accessible == null) {return null;}if (accessible instanceof Member) {Member member = (Member) accessible;if (Modifier.isPublic(member.getModifiers()) &&Modifier.isPublic(member.getDeclaringClass().getModifiers())) {return accessible;}}if (!accessible.isAccessible()) {accessible.setAccessible(true);}return accessible;}// ---------------------------------------------------------------------// Fluent Reflection API// ---------------------------------------------------------------------/*** 将给定字符串的开头改为小写.** @param string* @return*/@SuppressLint("DefaultLocale")private static String property(String string) {int length = string.length();if (length == 0) {return "";} else if (length == 1) {return string.toLowerCase();} else {return string.substring(0, 1).toLowerCase() + string.substring(1);}}private static Reflect on(Constructor constructor, Object... args) throws ReflectException {try {return on(accessible(constructor).newInstance(args));} catch (Exception e) {throw new ReflectException(e);}}private static Reflect on(Method method, Object object, Object... args) throwsReflectException {try {accessible(method);if (method.getReturnType() == void.class) {method.invoke(object, args);return on(object);} else {return on(method.invoke(object, args));}} catch (Exception e) {throw new ReflectException(e);}}/*** 取得内部维护的对象.*/private static Object unwrap(Object object) {if (object instanceof Reflect) {return ((Reflect) object).get();}return object;}/*** 将Object数组转换为其类型的数组.* 假设对象中包括null,我们用NULL.class取代.** @see Object#getClass()*/private static Class[] types(Object... values) {if (values == null) {return new Class[0];}Class[] result = new Class[values.length];for (int i = 0; i < values.length; i++) {Object value = values[i];result[i] = value == null ?NULL.class : value.getClass();}return result;}/*** 取得一个类,此操作会初始化类的static区域.** @see Class#forName(String)*/private static Class forName(String name) throws ReflectException {try {return Class.forName(name);} catch (Exception e) {throw new ReflectException(e);}}private static Class forName(String name, ClassLoader classLoader) throws ReflectException {try {return Class.forName(name, true, classLoader);} catch (Exception e) {throw new ReflectException(e);}}/*** 假设给定的Class是原始类型,那么将其包装为对象类型,* 否则返回本身.*/public static Class wrapper(Class type) {if (type == null) {return null;} else if (type.isPrimitive()) {if (boolean.class == type) {return Boolean.class;} else if (int.class == type) {return Integer.class;} else if (long.class == type) {return Long.class;} else if (short.class == type) {return Short.class;} else if (byte.class == type) {return Byte.class;} else if (double.class == type) {return Double.class;} else if (float.class == type) {return Float.class;} else if (char.class == type) {return Character.class;} else if (void.class == type) {return Void.class;}}return type;}/*** 取得内部维护的实际对象** @param * @return*/@SuppressWarnings("unchecked")public T get() {return (T) object;}/*** 设置指定字段为指定值** @param name* @param value* @return* @throws ReflectException*/public Reflect set(String name, Object value) throwsReflectException {try {Field field = field0(name);field.setAccessible(true);field.set(object, unwrap(value));return this;} catch (Exception e) {throw new ReflectException(e);}}/*** @param name* @param * @return* @throws ReflectException*/public T get(String name) throws ReflectException {return field(name).get();}/*** 取得指定名称的字段** @param name* @return* @throws ReflectException*/public Reflect field(String name) throws ReflectException {try {Field field = field0(name);return on(field.get(object));} catch (Exception e) {throw new ReflectException(e);}}private Field field0(String name) throws ReflectException {Class type = type();// 先尝试取得公有字段try {return type.getField(name);}//此时尝试非公有字段catch (NoSuchFieldException e) {do {try {return accessible(type.getDeclaredField(name));} catch (NoSuchFieldException ignore) {}type = type.getSuperclass();}while (type != null);throw new ReflectException(e);}}/*** 取得一个Map,map中的key为字段名,value为字段相应的反射工具类** @return*/public Map fields() {Map result = new LinkedHashMap();Class type = type();do {for (Field field : type.getDeclaredFields()) {if (!isClass ^ Modifier.isStatic(field.getModifiers())) {String name = field.getName();if (!result.containsKey(name))result.put(name, field(name));}}type = type.getSuperclass();}while (type != null);return result;}/*** 调用指定的无參数方法** @param name* @return* @throws androidx.pluginmgr.reflect.ReflectException*/public Reflect call(String name) throws ReflectException {return call(name, new Object[0]);}/*** 调用方法依据传入的參数** @param name* @param args* @return* @throws androidx.pluginmgr.reflect.ReflectException*/public Reflect call(String name, Object... args) throws ReflectException {Class[] types = types(args);try {Method method = exactMethod(name, types);return on(method, object, args);} catch (NoSuchMethodException e) {try {Method method = similarMethod(name, types);return on(method, object, args);} catch (NoSuchMethodException e1) {throw new ReflectException(e1);}}}private Method exactMethod(String name, Class[] types) throws NoSuchMethodException {Class type = type();try {return type.getMethod(name, types);} catch (NoSuchMethodException e) {do {try {return type.getDeclaredMethod(name, types);} catch (NoSuchMethodException ignore) {}type = type.getSuperclass();}while (type != null);throw new NoSuchMethodException();}}/*** 依据參数和名称匹配方法,假设找不到方法,*/private Method similarMethod(String name, Class[] types) throws NoSuchMethodException {Class type = type();for (Method method : type.getMethods()) {if (isSimilarSignature(method, name, types)) {return method;}}do {for (Method method : type.getDeclaredMethods()) {if (isSimilarSignature(method, name, types)) {return method;}}type = type.getSuperclass();}while (type != null);throw new NoSuchMethodException("No similar method " + name + " with params " + Arrays.toString(types) + " could be found on type " + type() + ".");}private boolean isSimilarSignature(Method possiblyMatchingMethod, String desiredMethodName, Class[] desiredParamTypes) {return possiblyMatchingMethod.getName().equals(desiredMethodName) && match(possiblyMatchingMethod.getParameterTypes(), desiredParamTypes);}/*** 创建一个实例通过默认构造器** @return* @throws androidx.pluginmgr.reflect.ReflectException*/public Reflect create() throws ReflectException {return create(new Object[0]);}/*** 创建一个实例依据传入的參数** @param args* @return* @throws ReflectException*/public Reflect create(Object... args) throws ReflectException {Class[] types = types(args);try {Constructor constructor = type().getDeclaredConstructor(types);return on(constructor, args);} catch (NoSuchMethodException e) {for (Constructor constructor : type().getDeclaredConstructors()) {if (match(constructor.getParameterTypes(), types)) {return on(constructor, args);}}throw new ReflectException(e);}}/*** 创建一个动态代理依据传入的类型.* 假设我们正在维护的是一个Map,那么当调用出现异常时我们将从Map中取值.** @param proxyType 须要动态代理的类型* @return 动态代理生成的对象*/@SuppressWarnings("unchecked")public

P as(Class

proxyType) {final boolean isMap = (object instanceof Map);final InvocationHandler handler = new InvocationHandler() {@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {String name = method.getName();try {return on(object).call(name, args).get();} catch (ReflectException e) {if (isMap) {Map map = (Map) object;int length = (args == null ?0 : args.length);if (length == 0 && name.startsWith("get")) {return map.get(property(name.substring(3)));} else if (length == 0 && name.startsWith("is")) {return map.get(property(name.substring(2)));} else if (length == 1 && name.startsWith("set")) {map.put(property(name.substring(3)), args[0]);return null;}}throw e;}}};return (P) Proxy.newProxyInstance(proxyType.getClassLoader(), new Class[]{proxyType}, handler);}/*** 检查两个数组的类型是否匹配,假设数组中包括原始类型,将它们转换为相应的包装类型.*/private boolean match(Class[] declaredTypes, Class[] actualTypes) {if (declaredTypes.length == actualTypes.length) {for (int i = 0; i < actualTypes.length; i++) {if (actualTypes[i] == NULL.class)continue;if (wrapper(declaredTypes[i]).isAssignableFrom(wrapper(actualTypes[i])))continue;return false;}return true;} else {return false;}}/*** {@inheritDoc}*/@Overridepublic int hashCode() {return object.hashCode();}/*** {@inheritDoc}*/@Overridepublic boolean equals(Object obj) {if (obj instanceof Reflect) {return object.equals(((Reflect) obj).get());}return false;}/*** {@inheritDoc}*/@Overridepublic String toString() {return object.toString();}/*** 取得我们正在反射的对象的类型.** @see Object#getClass()*/public Class type() {if (isClass) {return (Class) object;} else {return object.getClass();}}}

ReflectException

/****/
public class ReflectException extends RuntimeException {private static final long serialVersionUID = 663038727503637969L;public ReflectException(String message) {super(message);}public ReflectException(String message, Throwable cause) {super(message, cause);}public ReflectException() {super();}public ReflectException(Throwable cause) {super(cause);}
}

接下来是activityThread的代理类

import Reflect;import android.app.ActivityThread;
import android.app.Application;
import android.app.Instrumentation;public class DelegateActivityThread {private static DelegateActivityThread SINGLETOPN = new DelegateActivityThread();private Reflect mActivityThreadReflect;public DelegateActivityThread() {mActivityThreadReflect = Reflect.on(ActivityThread.currentActivityThread());}public static DelegateActivityThread getSingletion() {return SINGLETOPN;}public Application getInitialApplication() {return mActivityThreadReflect.get("mInitialApplication");}public Instrumentation getInstrumentation() {return mActivityThreadReflect.get("mInstrumentation");}public void setInstrumentation(Instrumentation newInstrumentation) {mActivityThreadReflect.set("mInstrumentation", newInstrumentation);}
}

要在Instrumentation进行咱们自己操作的继承类DelegateInstrumentation

import android.annotation.TargetApi;
import android.app.Activity;
import android.app.Application;
import android.app.Fragment;
import android.app.Instrumentation;
import android.app.UiAutomation;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.ActivityInfo;
import android.os.Build;
import android.os.Bundle;
import android.os.IBinder;
import android.util.Log;
import android.view.KeyEvent;
import android.view.MotionEvent;public class DelegateInstrumentation extends Instrumentation {private Instrumentation mBase;/*** @param mBase 真正的Instrumentation*/public DelegateInstrumentation(Instrumentation mBase) {this.mBase = mBase;}@Overridepublic void onCreate(Bundle arguments) {mBase.onCreate(arguments);}@Overridepublic void start() {mBase.start();}@Overridepublic void onStart() {mBase.onStart();}@Overridepublic boolean onException(Object obj, Throwable e) {return mBase.onException(obj, e);}@Overridepublic void sendStatus(int resultCode, Bundle results) {mBase.sendStatus(resultCode, results);}@Overridepublic void finish(int resultCode, Bundle results) {mBase.finish(resultCode, results);}@Overridepublic void setAutomaticPerformanceSnapshots() {mBase.setAutomaticPerformanceSnapshots();}@Overridepublic void startPerformanceSnapshot() {mBase.startPerformanceSnapshot();}@Overridepublic void endPerformanceSnapshot() {mBase.endPerformanceSnapshot();}@Overridepublic void onDestroy() {mBase.onDestroy();}@Overridepublic Context getContext() {return mBase.getContext();}@Overridepublic ComponentName getComponentName() {return mBase.getComponentName();}@Overridepublic Context getTargetContext() {return mBase.getTargetContext();}@Overridepublic boolean isProfiling() {return mBase.isProfiling();}@Overridepublic void startProfiling() {mBase.startProfiling();}@Overridepublic void stopProfiling() {mBase.stopProfiling();}@Overridepublic void setInTouchMode(boolean inTouch) {mBase.setInTouchMode(inTouch);}@Overridepublic void waitForIdle(Runnable recipient) {mBase.waitForIdle(recipient);}@Overridepublic void waitForIdleSync() {mBase.waitForIdleSync();}@Overridepublic void runOnMainSync(Runnable runner) {mBase.runOnMainSync(runner);}@Overridepublic Activity startActivitySync(Intent intent) {return mBase.startActivitySync(intent);}@Overridepublic void addMonitor(ActivityMonitor monitor) {mBase.addMonitor(monitor);}@Overridepublic ActivityMonitor addMonitor(IntentFilter filter, ActivityResult result, boolean block) {return mBase.addMonitor(filter, result, block);}@Overridepublic ActivityMonitor addMonitor(String cls, ActivityResult result, boolean block) {return mBase.addMonitor(cls, result, block);}@Overridepublic boolean checkMonitorHit(ActivityMonitor monitor, int minHits) {return mBase.checkMonitorHit(monitor, minHits);}@Overridepublic Activity waitForMonitor(ActivityMonitor monitor) {return mBase.waitForMonitor(monitor);}@Overridepublic Activity waitForMonitorWithTimeout(ActivityMonitor monitor, long timeOut) {return mBase.waitForMonitorWithTimeout(monitor, timeOut);}@Overridepublic void removeMonitor(ActivityMonitor monitor) {mBase.removeMonitor(monitor);}@Overridepublic boolean invokeMenuActionSync(Activity targetActivity, int id, int flag) {return mBase.invokeMenuActionSync(targetActivity, id, flag);}@Overridepublic boolean invokeContextMenuAction(Activity targetActivity, int id, int flag) {return mBase.invokeContextMenuAction(targetActivity, id, flag);}@Overridepublic void sendStringSync(String text) {mBase.sendStringSync(text);}@Overridepublic void sendKeySync(KeyEvent event) {mBase.sendKeySync(event);}@Overridepublic void sendKeyDownUpSync(int key) {mBase.sendKeyDownUpSync(key);}@Overridepublic void sendCharacterSync(int keyCode) {mBase.sendCharacterSync(keyCode);}@Overridepublic void sendPointerSync(MotionEvent event) {mBase.sendPointerSync(event);}@Overridepublic void sendTrackballEventSync(MotionEvent event) {mBase.sendTrackballEventSync(event);}@Overridepublic Application newApplication(ClassLoader cl, String className, Context context) throws InstantiationException, IllegalAccessException, ClassNotFoundException {return mBase.newApplication(cl, className, context);}@Overridepublic void callApplicationOnCreate(Application app) {mBase.callApplicationOnCreate(app);}@Overridepublic Activity newActivity(Class clazz, Context context, IBinder token, Application application, Intent intent, ActivityInfo info, CharSequence title, Activity parent, String id, Object lastNonConfigurationInstance) throws InstantiationException, IllegalAccessException {return mBase.newActivity(clazz, context, token, application, intent, info, title, parent, id, lastNonConfigurationInstance);}@Overridepublic Activity newActivity(ClassLoader cl, String className, Intent intent) throws InstantiationException, IllegalAccessException, ClassNotFoundException {return mBase.newActivity(cl, className, intent);}@Overridepublic void callActivityOnCreate(Activity activity, Bundle icicle) {mBase.callActivityOnCreate(activity, icicle);}@Overridepublic void callActivityOnDestroy(Activity activity) {mBase.callActivityOnDestroy(activity);}@Overridepublic void callActivityOnRestoreInstanceState(Activity activity, Bundle savedInstanceState) {mBase.callActivityOnRestoreInstanceState(activity, savedInstanceState);}@Overridepublic void callActivityOnPostCreate(Activity activity, Bundle icicle) {mBase.callActivityOnPostCreate(activity, icicle);}@Overridepublic void callActivityOnNewIntent(Activity activity, Intent intent) {mBase.callActivityOnNewIntent(activity, intent);}@Overridepublic void callActivityOnStart(Activity activity) {mBase.callActivityOnStart(activity);}@Overridepublic void callActivityOnRestart(Activity activity) {mBase.callActivityOnRestart(activity);}@Overridepublic void callActivityOnResume(Activity activity) {mBase.callActivityOnResume(activity);}@Overridepublic void callActivityOnStop(Activity activity) {mBase.callActivityOnStop(activity);}@Overridepublic void callActivityOnSaveInstanceState(Activity activity, Bundle outState) {mBase.callActivityOnSaveInstanceState(activity, outState);}@Overridepublic void callActivityOnPause(Activity activity) {mBase.callActivityOnPause(activity);}@TargetApi(Build.VERSION_CODES.CUPCAKE)@Overridepublic void callActivityOnUserLeaving(Activity activity) {mBase.callActivityOnUserLeaving(activity);}@Overridepublic void startAllocCounting() {mBase.startAllocCounting();}@Overridepublic void stopAllocCounting() {mBase.stopAllocCounting();}@Overridepublic Bundle getAllocCounts() {return mBase.getAllocCounts();}@Overridepublic Bundle getBinderCounts() {return mBase.getBinderCounts();}@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2)@Overridepublic UiAutomation getUiAutomation() {return mBase.getUiAutomation();}@Overridepublic ActivityResult execStartActivity(Context who, IBinder contextThread, IBinder token, Fragment fragment, Intent intent, int requestCode) {doMyOperation();return mBase.execStartActivity(who, contextThread, token, fragment, intent, requestCode);}@Overridepublic ActivityResult execStartActivity(Context who, IBinder contextThread, IBinder token, Fragment fragment, Intent intent, int requestCode, Bundle options) {doMyOperation();return mBase.execStartActivity(who, contextThread, token, fragment, intent, requestCode, options);}@Overridepublic ActivityResult execStartActivity(Context who, IBinder contextThread, IBinder token, Activity target, Intent intent, int requestCode) {doMyOperation();return mBase.execStartActivity(who, contextThread, token, target, intent, requestCode);}@Overridepublic ActivityResult execStartActivity(Context who, IBinder contextThread, IBinder token, Activity target, Intent intent, int requestCode, Bundle options) {doMyOperation();return mBase.execStartActivity(who, contextThread, token, target, intent, requestCode, options);}public void doMyOperation() {}}

上面的doMyOperation是处理咱们业务逻辑的函数。

在Application里面进行初始化的类ActivityManager;

import android.app.Instrumentation;
import android.content.Context;
import android.os.Looper;public class ActivityManager {private static ActivityManager SINGLETON;private Context mContext;private ActivityManager(Context context) {if (!isMainThread()) {return;}mContext = context;DelegateActivityThread delegateActivityThread = DelegateActivityThread.getSingletion();Instrumentation originInstrumentation = delegateActivityThread.getInstrumentation();if (!(originInstrumentation instanceof DelegateInstrumentation)) {DelegateInstrumentation delegateInstrumentation = new DelegateInstrumentation(originInstrumentation);delegateActivityThread.setInstrumentation(delegateInstrumentation);}}public static void init(Context context) {if (null != SINGLETON) {return;}SINGLETON = new ActivityManager(context);}private boolean isMainThread() {return Looper.getMainLooper() == Looper.myLooper();}}

在Applicaiton进行初始化:

ActivityManager.init(this);

2.3 利用list自己管理的acitvity栈

无需多说。直接上代码。

import java.util.ArrayList;
import java.util.List;import android.app.Activity;/*** activity的管理栈,方便进行activity进行查找、处理** 眼下只适用于单线程** */
public class ActivityManager {private static ActivityManager SINGLETON = new ActivityManager();private static List mAcitivityList = new ArrayList();private ActivityManager() {if (null == mAcitivityList) {mAcitivityList = new ArrayList();}mAcitivityList.clear();}public static ActivityManager getInstance() {if (null == SINGLETON) {SINGLETON = new ActivityManager();}return SINGLETON;}/*** activity入栈** */public void addActivity(Activity activity) {staticUserPage(activity);mAcitivityList.add(activity);}/*** activity出栈** */public void popActivity(Activity activity) {if (null == mAcitivityList) {return;}int total = mAcitivityList.size();if (total > 0) {mAcitivityList.remove(activity);}}/*** 获取栈顶的activity* */public Activity getTopActivity() {int total = mAcitivityList.size();if (total > 0) {Activity currentActivity = mAcitivityList.get(total - 1);return currentActivity;}return null;}/*** 清空全部的activity* */public void onExit() {if (null != mAcitivityList) {mAcitivityList.clear();}mAcitivityList = null;}}

最后

从一个LauncherActivity到APP进程的activity,Activity的栈,在其中的工作大致如下:

  • Activity的启动一般可以通过startActivity()来进行,通过Instrumentation.execStartActivity(),最终会通知到AMS来进行Activity的启动。
  • AMS通过binder线程获知了需要启动Activity的任务,让ActivityStarter去完成activity的启动。
  • ActivityStarter在一连串的startActivity()调用过程中,为要启动的Activity创建了一个ActivityRecord。
  • 最后进入到startActivityUnchecked(),根据Activity的启动模式与启动标识符的不同进行不同的处理。
  • 如果这个Activity是新进程的Activity,将会通知AMS先进行APP进程的启动,APP进程的application启动完成后,会通知AMS,application初始完成,并将APP进程的binder代理交给AMS,AMS再通过ActivityStartSupervisor来realStartActivityLocked()->app.thread.scheduleLaunchActivity()来通知APP进程,可以启动activity了。
  • 如果这个Activity是本进程发起的启动,那么就会根据发起者Activity的启动模式以及新Activity的启动模式综合判断,是复用Activity接着调用newIntent()呢,还是新建一个Activity,然后也进入到realStartActivityLocked()->app.thread.scheduleLaunchActivity()来启动新的Activity.

相关内容

热门资讯

清朝有很多有名的历史人物,能给... 清朝有很多有名的历史人物,能给大家说几个清朝的历史人物吗?林则徐,张之洞,乾隆皇帝,曾国藩,朱耷,这...
曹丕的“太子四友”指的是谁 曹丕的“太子四友”指的是谁首先说,曹丕这四个,陈群司马懿是顶级的谋士和政治家,吴质有些小聪明,朱铄不...
在这次遇难者中存在了几名幸存者... 在这次遇难者中存在了几名幸存者。这句话是不是逻辑错误这句话的逻辑没有问题,有问题的是用词不当。遇难者...
在中国古代,有许多充满哲学智慧... 在中国古代,有许多充满哲学智慧的成语典故、寓言故事,如...在中国古代,有许多充满哲学智慧的成语典故...
清澈的意思是什么,… 清澈的意思是什么,…清净而明澈清而透明【造句】看着他清澈而又天真的眼眸,我的心久久不能平静……
蚂蚁森林合种爱情树一方退出怎么... 蚂蚁森林合种爱情树一方退出怎么找回来两个人合种的爱情树,我退出来,我怎么再次加入进去继续合作那个树?...
有好看的古代修炼小说推荐吗? 有好看的古代修炼小说推荐吗?古代重生穿越修炼......让我帮你找一下这些古代修炼的小说,找到这些类...
女主重生爱上前世辜负的人 女主重生爱上前世辜负的人重生我是你正妻渣女重生之竹马重生之弃渣重生之夫君可欺重生之换我疼你重生妇归来...
华胥引有广播剧吗 华胥引有广播剧吗现有的华胥引的广播剧是忆语广播剧社出品的,只有十三月和杯(这个是错字,请无视,居然输...
选文韩麦尔先生在说了,我的朋友... 选文韩麦尔先生在说了,我的朋友们我就要离开你们呢了,再见了银头鲑鱼tj75rt6yturdrruv ...
中通快递从北京保定市到广东揭阳... 中通快递从北京保定市到广东揭阳普宁要多久?中通快递从北京保定市到广东揭阳普宁要多久?从北京到广东需要...
关于离婚悲伤的歌曲 关于离婚悲伤的歌曲关于离婚悲伤的歌曲林俊杰《可惜没如果》 张靓颖《我走以后》 金志文《流着泪说分手》...
形容文笔差怎么说啊? 形容文笔差怎么说啊?哥哥姐姐,麻烦问下,我是做文员的,形容文案方面的工作很差应该怎么说啊?粗鄙怎么样...
我想做未婚妈妈,可行吗? 我想做未婚妈妈,可行吗?没关系吧?我同学好多他们妈妈都是30岁以后省得他们,都没事啊,但是如果你自己...
如何在两个excel表格里筛选... 如何在两个excel表格里筛选出重复的名字如何在两个excel表格里筛选出重复的名字1、电脑打开EX...
且试天下 哪些小说是用白绫做武... 且试天下 哪些小说是用白绫做武器的?神雕侠侣吖- -..小龙女一开始就是用白绫的聊斋 辛十四娘嘿嘿~...
自带高冷体质,笑起来温暖又治愈... 自带高冷体质,笑起来温暖又治愈的星座,你了解吗?虽然天生高冷体质,但是笑起来特别的温暖治愈的新作用天...
火星未解之谜 火星未解之谜多列举一些,每个事例最好长一点,谢啦~“火星人脸”, “地表被水冲击河道”,“原始大气和...
我是1991年10月4号生的,... 我是1991年10月4号生的,是什么星座啊有的说是处女座有的说是天平座,糊涂了,到底是什么啊很负责任...
梦见白狐狸,然后当时我骑着自行... 梦见白狐狸,然后当时我骑着自行车,我想躲开它,他很凶的的追赶我,最后它向我扑了过来,然后我就醒乐.你...