如何查询建造师证有没有在项目上/优化网站关键词优化
概述
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));}/*** 依据指定的类构建反射工具类* <p>* 当你须要訪问静态字段的时候本方法适合你,* 你还能够通过调用 {@link #create(Object...)} 创建一个对象.** @param clazz 须要构建反射工具类的类* @return 反射工具类*/public static Reflect on(Class<?> clazz) {return new Reflect(clazz);}// ---------------------------------------------------------------------// 构造器// ---------------------------------------------------------------------/*** Wrap an object.* <p>* 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 <T>* @return*/public static <T extends AccessibleObject> 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 <T>* @return*/@SuppressWarnings("unchecked")public <T> 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 <T>* @return* @throws ReflectException*/public <T> 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<String, Reflect> fields() {Map<String, Reflect> result = new LinkedHashMap<String, Reflect>();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> P as(Class<P> 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<String, Object> map = (Map<String, Object>) 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<Activity> mAcitivityList = new ArrayList<Activity>();private ActivityManager() {if (null == mAcitivityList) {mAcitivityList = new ArrayList<Activity>();}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.
相关文章:

【我的Android开发】AMS中Activity栈管理
概述 Activity栈管理是AMS的另一个重要功能,栈管理又和Activity的启动模式和startActivity时所设置的Flag息息相关,Activity栈管理的主要处理逻辑是在ActivityStarter#startActivityUnchecked方法中,本文也会围绕着这个方法进进出出…...

C++源程序的构成————学习笔记
以下内容为,在学校上课时的课堂总结,偶尔我也会扩展一些内容内容仅供参考,欢迎大佬的指正简单的C程序#include <iostream> using namespace std;int main() {int x0;int y 0;cout << "请输入x,y的值"<<endl;cin…...

Spark Catalyst
Spark Catalyst逻辑计划逻辑计划解析逻辑计划优化Catalyst 规则优化过程物理计划Spark PlanJoinSelection生成 Physical PlanEnsureRequirementsSpark SQL 端到端的优化流程: Catalyst 优化器 : 包含逻辑优化/物理优化Tungsten : Spark SQL的优化过程 : 逻辑计划 …...

element 远程搜索下拉加载
created() { this.getList(); this.getGroupList(); }, directives: { /** 下拉框懒加载 */ “el-select-loadmore”: { bind(el, binding) { const SELECTWRAP_DOM el.querySelector( “.el-select-dropdown .el-select-dropdown__wrap” ); SELECTWRAP_DOM.addEventListener…...

空间复杂度与顺序表的具体实现操作(1)
最近更新的少,主要是因为参加了ACM竞赛空间复杂度空间复杂度也是一个数学表达式,是对一个算法在运行过程中临时占用存储空间大小的量度 。空间复杂度不是程序占用了多少bytes的空间,因为这个也没太大意义,所以空间复杂度算的是变量…...

【springmvc】Rest ful风格
RESTful 1、RESTful简介 REST:Representational State Transfer,表现层资源状态转移。 a>资源 资源是一种看待服务器的方式,即,将服务器看作是由很多离散的资源组成。每个资源是服务器上一个可命名的抽象概念。因为资源是一…...

华为OD机试真题Python实现【用户调度】真题+解题思路+代码(20222023)
用户调度 题目 在通信系统中有一个常见的问题是对用户进行不同策略的调度,会得到不同系统消耗的性能。 假设由N个待串行用户,每个用户可以使用A/B/C三种不同的调度策略。 不同的策略会消耗不同的系统资源,请你根据如下规则进行用户调度,并返回总的消耗资源数。 规则是: …...

JavaSE学习笔记总结day19
今日内容 二、线程安全的集合 三、死锁 四、线程通信 五、生产者消费者 六、线程池 零、 复习昨日 创建线程的几种方式 1) 继承 2) 实现Runnable 3) callable接口 Future接口 4) 线程池 启动线程的方法 start() 线程的几种状态 什么是线程不安全 setName getName Thread.curr…...

FreeSql使用
目的: 1.方库分表 2.主从分离 3.分布式事务 过程: 官网:指南 | FreeSql 官方文档 1.Startup.cs 添加配置(本地数据库MySql) ConfigureServices: Func<IServiceProvider, IFreeSql> fsql r >{IFreeSql …...

Hadoop集群搭建,基于3.3.4hadoop和centos8【图文教程-从零开始搭建Hadoop集群】,常见问题解决
Hadoop集群搭建,基于3.3.4hadoop和centos8【小白图文教程-从零开始搭建Hadoop集群】,常见问题解决Hadoop集群搭建,基于3.3.4hadoop1.虚拟机的创建1.1 第一台虚拟机的创建1.2 第一台虚拟机的安装1.3 第一台虚拟机的网络配置1.3.1 主机名和IP映…...

UE4 材质学习 (焚烧材质)
效果步骤随便从网上下载一张图片(地址:链接/链接),导入UE中新建一个材质函数这里命名为“E_Function”双击打开该材质函数,由于需要输出变发光和变透明两种效果,因此这里需要两个输出节点:分别命…...

【c++】STL常用算法2—常用查找算法
文章目录常用查找算法findfind_ifadjacent_findbinary_searchcountcount_if常用查找算法 算法简介: find//查找元素 find_if//按条件查找元素 adjacent_find//查找相邻重复元素 binary_search//二分查找法 count//统计元素个数 count_if//按条件统计元素个数find …...

史上最全最详细的Java架构师成长路径图,程序员必备
从新手码农到高级架构师,要经过几步?要多努力,才能成为为人倚重的技术专家?本文将为你带来一张程序员发展路径图,但你需要知道的是,天下没有普适的道理,具体问题还需具体分析,实践才…...

第五章 事务管理
1.事务概念 *什么是事务:事务是数据库操作最基本单元,逻辑上是一组操作,要么都成功,要么都失败 *事务的特性(ACID):原子性、隔离性、一致性、持久性 2.搭建事务操作环境 *模拟场景ÿ…...

Redis:主从同步
Redis:主从同步一. 概述二. 原理(1) 全量同步(2) 增量同步(3) 优化Redis主从集群三. 总结一. 概述 引入: Redis主从集群采用一个Master负责写,多个Slave负责读的方式(读多写少),那么如何让读取数据时多个从…...

Unity Animator.Play(stateName, layer, normalizedTime) 播放动画函数用法
原理 接口: public void Play(string stateName, int layer -1, float normalizedTime float.NegativeInfinity);参数含义stateName动画状态机的某个状态名字layer第几层的动画状态机,-1 表示播放第一个状态或者第一个哈希到的状态normalizedTime从s…...

python学习——【第三弹】
前言 上一篇文章 python学习——【第二弹】中学习了python中的运算符内容,这篇文章接着学习python中的流程控制语句。 流程控制指的是代码运行逻辑、分支走向、循环控制,是真正体现我们程序执行顺序的操作。流程控制一般分为顺序执行、条件判断和循环控…...

科技云报道:AI大模型背后,竟是惊人的碳排放
科技云报道原创。 自从ChatGPT这样的大型语言模型在全球引起轰动以来,很少有人注意到,训练和运行大型语言模型正在产生惊人的碳排放量。 虽然OpenAI和谷歌都没有说过他们各自产品的计算成本是多少,但据第三方研究人员分析,ChatG…...

如何根据实际需求选择合适的三维实景建模方式?
随着实景三维中国建设的推进,对三维实景建模的数字化需求大幅增加。由于三维实景建模具有采集速度快、计算精度高等建模优势,引起了各个行业的高度关注。三维实景建模是一种应用数码相机或者激光扫描仪对现有场景进行多角度环视拍摄,然后利用…...

CENTO OS上的网络安全工具(十八)ClickHouse及编程环境部署
这篇其实去年就写好了,孰知就在12月31日那一天打进决赛圈,一躺,二过年,三休假,四加班,居然到了三个月以后,才有机会将它发出来…… 一年也就四个季度不是,实在是光阴荏苒,…...

Java中class文件的格式
常见的class文件格式如下图所示,下面我将对一下格式一一作出解释。 一、magic 该部分主要是对语言类型的规范,只有magic这个部分是CAFEBABE时才能被检测为Java语言,否则则不是。 二、minor version和major version minor version主要表示了…...

C++排序算法
排序算法复习 冒泡排序 链接:https://www.runoob.com/w3cnote/bubble-sort.html 每次循环对比【相邻】两个元素,将最大的元素放到数组最后 void bubbleSort(int* arr, int n){//每次确认一个元素的最终位置,循环n-1次即可确认全部元素的最…...

JAVA后端部署项目三步走
1. JAVA部署项目三步走 1.1 查看 运行的端口 lsof -i:8804 (8804 为端口) 发现端口25111被监听 1.2 杀死进程,终止程序 pid 为进程号 kill -9 pid 1.3 后台运行jar包 nohup java -jar -Xms128M -Xmx256M -XX:MetaspaceSize128M -XX:MaxM…...

php使用zookeeper实现分布式锁
介绍 一、zookeeper和redis实现分布式锁的对比 1、redis 分布式场景应用比较广泛,redis分布式锁,其实需要自己不断去尝试获取锁,比较消耗性能;zk分布式锁,获取不到锁,注册个监听器即可,不需要不…...

力扣-可回收且低脂的产品
大家好,我是空空star,本篇带大家了解一道超级超级超级简单的力扣sql练习题。 文章目录前言一、题目:1757. 可回收且低脂的产品二、解题1.正确示范①提交SQL运行结果2.正确示范②提交SQL运行结果3.正确示范③提交SQL运行结果4.正确示范④提交S…...

代码随想录刷题-数组-二分查找
文章目录写在前面原理习题题目1思路和代码题目-2写在前面 这个专栏是记录我刷代码随想录过程中的随想和总结。每一小节都是根据自己的理解撰写的,文章比较短,主要是为了记录和督促自己。刷完一章后,我会再单独整理一篇文章来总结和分享。 本…...

HCIA复习1
HCIA复习 抽象语言---->编码 编码---->二进制 二进制--->电信号 处理电信号 OSI参考模型----OSI/RM 应用层 表示层 会话层 传输层 端口号:0-65535;1-1023是注明端口 网络层 IP地址 数据链路层 物理层 ARP协议 正向ARP---通过IP地址获取目的MAC地…...

Kotlin中的destructuring解构声明
开发中有时只是想分解一个包含多个字段的对象来初始化几个单独的变量。要实现这一点,可以使用Kotlin的解构声明。本文主要了解:“1、如何使用解构声明这种特性 2、底层是如何实现的 3、如何在你自己的类中实现它1、解构声明的使用解构声明&a…...

Kubernetes Pod 水平自动伸缩(HPA)
Pod 自动扩缩容 之前提到过通过手工执行kubectl scale命令和在Dashboard上操作可以实现Pod的扩缩容,但是这样毕竟需要每次去手工操作一次,而且指不定什么时候业务请求量就很大了,所以如果不能做到自动化的去扩缩容的话,这也是一个…...

钉钉、企业微信和飞书向“钱”看
在急剧变革的时候,不管黑猫白猫,要抓到老鼠才算好猫。如今,各互联网企业早已进入降本增效的新阶段。勒紧裤腰带过日子之下,能不能盈利、商业化空间有多大,就成为各个业务极为重要的考核指标。在各业务板块中࿰…...