邯鄲市住房和城鄉(xiāng)建設(shè)網(wǎng)站百度拍照搜題
概述
Activity棧管理是AMS的另一個重要功能,棧管理又和Activity的啟動模式和startActivity時所設(shè)置的Flag息息相關(guān),Activity棧管理的主要處理邏輯是在ActivityStarter#startActivityUnchecked
方法中,本文也會圍繞著這個方法進進出出,反復(fù)摩擦,直到腦海中都是它的形狀。goolge的工程師起名還是很講究的,為什么要帶Unchecked呢? Unchecked-不確定,是因為在執(zhí)行這個方法時,我要啟動哪個Activity還沒決定呢,具體為什么,我想看過這篇文章你就明白了。
Activity棧管理相關(guān)類
ActivityStackSupervisor
Activity棧的管理人
ActivityDisplay
表示一個屏幕,Android支持三種屏幕,主屏幕,外接屏幕,虛擬屏幕(投屏)【這個介紹是從其他地方看來的,并不確定】。一般在手機上只有主屏幕,此時ActivityStackSupervisor與ActivityDisplay都是系統(tǒng)唯一的
TaskRecord
是ActivityTask的記錄,TaskRecord是Activity棧的重要管理單元。形象一點理解,記得啟動模式的 singleTask 吧?意思就是讓這個Activity在單獨的TaskRecord中啟動?!癟ask":任務(wù)。
ActivityRecord
記錄著每個Activity的信息,ActivityRecord和Activity一一對應(yīng)。
ActivityStack
是ActivityRecord和TaskRecord兩者的統(tǒng)一上司,記錄著ActivityRecord和TaskRecord的狀態(tài)。
如果在只有主屏幕的設(shè)備上,他們之間的關(guān)系大概是這樣子的:
可以理解為一個屏幕上,可能會有很多個APP進程,每個APP進程對應(yīng)一個ActivityStack,也就是activity棧,其中由于Activity的啟動模式不同,又形成了若干個TaskRecord,其中包含著若干個ActivityRecord。
Activity 的四種啟動模式,以及啟動標識符
Standard
標準啟動模式,啟動Activity的時候向發(fā)起人的Task頂直接添加即可,返回時依次退出。
SingleTop
棧頂唯一,如果棧頂Activity不是要啟動的Activity,則會創(chuàng)建一個新的Activity實例,但如果棧頂Activity就是我們要啟動的Activity,就只會調(diào)用onNewIntent,而不去再重新創(chuàng)建一個實例。相比Standard,Standard不論如何,都會創(chuàng)建一個新的實例。
SingleTask
棧內(nèi)唯一。如果發(fā)起啟動的ActivityRecord所在的TaskRecord中,有要啟動的Activity對應(yīng)的ActivityRecord,則首先將TaskRecord中,目標Activity之上的所有ActivityRecord全都彈出,然后將所在TaskRecord變?yōu)锳ctivityStack的棧頂。
如果發(fā)起啟動的ActivityRecord所在的TaskRecord中,沒有要啟動的Activity對應(yīng)的ActivityRecord,則會在棧頂新建一個TaskRecord,并向其中實例化一個需要啟動的Activity對應(yīng)的ActivityRecord。
SingleInstance
獨占一個TaskRecord。啟動時,在ActivityStack中查找是否有相同的Activity,如果有,則用這個獨占TaskRecord的ActivityRecord對應(yīng)的Activity。否則新建一個TaskRecord,里面只有它存在。由singleInstance發(fā)起的啟動,不論是誰,都會在另一個task中啟動。
代碼實現(xiàn)
通過對"android.app.ActivityThread"進行反射。獲取android系統(tǒng)的activity棧
遍歷activity棧能夠得到當前應(yīng)用中的全部存活的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中調(diào)用上述方法時。你會發(fā)現(xiàn)activity列表activities中沒有當前的activity,這是由于當前activity還沒有被增加棧中??墒莖nResume中調(diào)用上面的函數(shù)。就發(fā)現(xiàn)當前activity已經(jīng)被增加棧中。
2.2 重寫Instrumentation
監(jiān)聽activity的聲明周期?,F(xiàn)實自己想要的操作。
首先"繞莊"操作,即在當前project的src文件夾以下新建anroid.app包,然后聲明ActivityThread、Instrumentation、LoadedApk三個文件。
ActivityThread類
package android.app;import android.content.pm.ApplicationInfo;public final class ActivityThread {/*** NOTICE: 必須在UI線程調(diào)用本方法,否則返回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屬于內(nèi)核實現(xiàn)類型,不能直接使用,否則會編譯出錯。
以下是一個反射的工具類,有l(wèi)ody大神設(shè)計
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)的反射工具類,* 使用起來就像直接調(diào)用一樣流暢易懂.**/
@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;}/*** 依據(jù)指定的類名構(gòu)建反射工具類** @param name 類的全名* @return 反射工具類* @throws 假設(shè)反射出現(xiàn)意外* @see #on(Class)*/public static Reflect on(String name) throws ReflectException {return on(forName(name));}/*** 從指定的類載入起尋找類,并構(gòu)建反射工具類** @param name 類的全名* @param classLoader 須要構(gòu)建工具類的類的類載入器* loaded.* @return 反射工具類* @throws ReflectException 假設(shè)反射出現(xiàn)意外* @see #on(Class)*/public static Reflect on(String name, ClassLoader classLoader) throws ReflectException {return on(forName(name, classLoader));}/*** 依據(jù)指定的類構(gòu)建反射工具類* <p>* 當你須要訪問靜態(tài)字段的時候本方法適合你,* 你還能夠通過調(diào)用 {@link #create(Object...)} 創(chuàng)建一個對象.** @param clazz 須要構(gòu)建反射工具類的類* @return 反射工具類*/public static Reflect on(Class<?> clazz) {return new Reflect(clazz);}// ---------------------------------------------------------------------// 構(gòu)造器// ---------------------------------------------------------------------/*** 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);}}/*** 取得內(nèi)部維護的對象.*/private static Object unwrap(Object object) {if (object instanceof Reflect) {return ((Reflect) object).get();}return object;}/*** 將Object數(shù)組轉(zhuǎn)換為其類型的數(shù)組.* 假設(shè)對象中包括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區(qū)域.** @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);}}/*** 假設(shè)給定的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;}/*** 取得內(nèi)部維護的實際對象** @param <T>* @return*/@SuppressWarnings("unchecked")public <T> T get() {return (T) object;}/*** 設(shè)置指定字段為指定值** @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為字段相應(yīng)的反射工具類** @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;}/*** 調(diào)用指定的無參數(shù)方法** @param name* @return* @throws androidx.pluginmgr.reflect.ReflectException*/public Reflect call(String name) throws ReflectException {return call(name, new Object[0]);}/*** 調(diào)用方法依據(jù)傳入的參數(shù)** @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();}}/*** 依據(jù)參數(shù)和名稱匹配方法,假設(shè)找不到方法,*/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);}/*** 創(chuàng)建一個實例通過默認構(gòu)造器** @return* @throws androidx.pluginmgr.reflect.ReflectException*/public Reflect create() throws ReflectException {return create(new Object[0]);}/*** 創(chuàng)建一個實例依據(jù)傳入的參數(shù)** @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);}}/*** 創(chuàng)建一個動態(tài)代理依據(jù)傳入的類型.* 假設(shè)我們正在維護的是一個Map,那么當調(diào)用出現(xiàn)異常時我們將從Map中取值.** @param proxyType 須要動態(tài)代理的類型* @return 動態(tài)代理生成的對象*/@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);}/*** 檢查兩個數(shù)組的類型是否匹配,假設(shè)數(shù)組中包括原始類型,將它們轉(zhuǎn)換為相應(yīng)的包裝類型.*/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是處理咱們業(yè)務(wù)邏輯的函數(shù)。
在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);}}/*** 獲取棧頂?shù)腶ctivity* */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的任務(wù),讓ActivityStarter去完成activity的啟動。
- ActivityStarter在一連串的startActivity()調(diào)用過程中,為要啟動的Activity創(chuàng)建了一個ActivityRecord。
- 最后進入到startActivityUnchecked(),根據(jù)Activity的啟動模式與啟動標識符的不同進行不同的處理。
- 如果這個Activity是新進程的Activity,將會通知AMS先進行APP進程的啟動,APP進程的application啟動完成后,會通知AMS,application初始完成,并將APP進程的binder代理交給AMS,AMS再通過ActivityStartSupervisor來realStartActivityLocked()->app.thread.scheduleLaunchActivity()來通知APP進程,可以啟動activity了。
- 如果這個Activity是本進程發(fā)起的啟動,那么就會根據(jù)發(fā)起者Activity的啟動模式以及新Activity的啟動模式綜合判斷,是復(fù)用Activity接著調(diào)用newIntent()呢,還是新建一個Activity,然后也進入到realStartActivityLocked()->app.thread.scheduleLaunchActivity()來啟動新的Activity.