instrumentation
英 [ˌɪnstrəmenˈteɪʃn] 美 [ˌɪnstrəmenˈteɪʃn]
n.(一套)仪器,仪表;器乐谱写
Instrumentation源码解释如下:
/**
- Base class for implementing application instrumentation code. When running
- with instrumentation turned on, this class will be instantiated for you
- before any of the application code, allowing you to monitor all of the
- interaction the system has with the application. An Instrumentation
- implementation is described to the system through an AndroidManifest.xml’s
- <instrumentation> tag.
*/
可以大概理解为所有与application有关的调用都会通过Instrumentation这样一个仪器来方便地观察到;换句话说就是,所有有关application的调用实际上都会通过Instrumentation;看一下其源码就可以看到它里面完成了许多功能:
public class Instrumentation {
private ActivityThread mThread = null;
private MessageQueue mMessageQueue = null;
private List mActivityMonitors;
public Application newApplication(ClassLoader cl, String className, Context context) {}
public Activity newActivity(ClassLoader cl, String className,
Intent intent) {}
public void callActivityOnNewIntent(Activity activity, Intent intent) {}
public ActivityResult execStartActivity(){}
}
二、Activity启动流程分析
例如App1要启动App2的一个Activity;Activity启动流程分析如下:
1. App1中的SampleActivity1启动App2的SampleActivity2
public class SampleActivity1 {
public void onClick() {
Intent intent = getPackageManager().getLaunchIntentForPackage(“com.app2.sample”);
startActivity(intent);
}
}
2. Activity源码分析
public class Activity {
public void startActivity(Intent intent) {
this.startActivity(intent, null);
}
public void startActivity(Intent intent, @Nullable Bundle options) {
// …
startActivityForResult(intent, -1);
}
public void startActivityForResult(@RequiresPermission Intent intent, int requestCode, @Nullable Bundle options) {
// 省略部分代码…
options = transferSpringboardActivityOptions(options);
Instrumentation.ActivityResult ar = mInstrumentation.execStartActivity(this, mMainThread.getApplicationThread(), mToken, this,intent, requestCode, options);
if (ar != null) {
mMainThread.sendActivityResult(mToken, mEmbeddedID, requestCode, ar.getResultCode(), ar.getResultData());
}
}
}
可以看到,Activity的startActivity最终都调用到了Instrumentation里面;
3. Instrumentation源码分析
继续分析Instrumentation的execStartActivity()方法:
public class Instrumentation {
/**
- 可以看到传递的参数中比较重要的几个:
-
- context who:就是前面的SampleActivity1
-
- IBinder contextThread:传的value是mMainThread.getApplicationThread(),即当前APP进程,这样AMS进程才可以通过IBinder与App1进程通信(比如将结果返回,就需要binder通信)
-
- IBinder token:又见IBinder,那一定也是别的进程需要通过这个IBinder进行通信
-
- Intent intent:启动参数
**/
public ActivityResult execStartActivity(
Context who, IBinder contextThread, IBinder token, Activity target,
Intent intent, int requestCode, Bundle options) {
IApplicationThread whoThread = (IApplicationThread) contextThread;
// 省略部分代码…
try {
int result = ActivityTaskManager.getService()
.startActivity(whoThread, who.getBasePackageName(), intent,
intent.resolveTypeIfNeeded(who.getContentResolver()),
token, target != null ? target.mEmbeddedID : null,
requestCode, 0, null, options);
checkStartActivityResult(result, intent);
} catch (RemoteException e) {
throw new RuntimeException(“Failure from system”, e);
}
return null;
}
}
- Intent intent:启动参数
可以看到,又继续调用到了ActivityTaskManager.getService().startActivity()里面。
ps. 在android-28源码中是调用到了ActivityManager.getService().startActivity()里面,更老版本android源码中是调用了ActivityManagerNative.getDefault(),原理都类似,都是调用返回一个代理,最终到了系统进程去执行后续调起逻辑。
4. ActivityTaskManager源码分析
@SystemService(Context.ACTIVITY_TASK_SERVICE)
public class ActivityTaskManager {
public static IActivityTaskManager getService() {
return IActivityTaskManagerSingleton.get();
}
private static final Singleton IActivityTaskManagerSingleton =
new Singleton() {
@Override
protected IActivityTaskManager create() {
final IBinder b = ServiceManager.getService(Context.ACTIVITY_TASK_SERVICE);
return IActivityTaskManager.Stub.asInterface(b);
}
};
}
可以看出,ActivityTaskManager.getService()调用得到IBinder的proxy继续执行后续代码,这样就就调用到了系统进程里面继续执行;ActivityTaskManager是系统启动期间就注册的一个binder service,其注册代码如下:
@SystemApi
public final class SystemServiceRegistry {
static {
registerService(Context.ACTIVITY_TASK_SERVICE, ActivityTaskManager.class,
new CachedServiceFetcher() {
@Override
public ActivityTaskManager createService(ContextImpl ctx) {
return new ActivityTaskManager(
ctx.getOuterContext(), ctx.mMainThread.getHandler());
}});
}
接下来继续分析系统进程中startActivity()的执行步骤;
5. ActivityTaskManagerService源码分析
public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
public final int startActivity(IApplicationThread caller, String callingPackage,
Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
resultWho, requestCode, startFlags, profilerInfo, bOptions,
UserHandle.getCallingUserId());
}
int startActivityAsUser(IApplicationThread caller, String callingPackage,
Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId,
boolean validateIncomingUser) {
// 省略部分代码…
// getActivityStartController().obtainStarter返回一个ActivityStarter对象,下面继续分析ActivityStarter
return getActivityStartController().obtainStarter(intent, “startActivityAsUser”)
.setCaller(caller)
.setCallingPackage(callingPackage)
.setResolvedType(resolvedType)
.setResultTo(resultTo)
.setResultWho(resultWho)
.setRequestCode(requestCode)
.setStartFlags(startFlags)
.setProfilerInfo(profilerInfo)
.setActivityOptions(bOptions)
.setMayWait(userId)
.execute();
}
}
6. ActivityStarter源码分析
ActivityStarter负责处理intent中flag、启动模式等参数;
class ActivityStarter {
int execute() {
try {
// …
return startActivity(mRequest.caller, mRequest.intent, mRequest.ephemeralIntent,
mRequest.resolvedType, mRequest.activityInfo, mRequest.resolveInfo,
mRequest.voiceSession, mRequest.voiceInteractor, mRequest.resultTo,
mRequest.resultWho, mRequest.requestCode, mRequest.callingPid,
mRequest.callingUid, mRequest.callingPackage, mRequest.realCallingPid,
mRequest.realCallingUid, mRequest.startFlags, mRequest.activityOptions,
mRequest.ignoreTargetSecurity, mRequest.componentSpecified,
mRequest.outActivity, mRequest.inTask, mRequest.reason,
mRequest.allowPendingRemoteAnimationRegistryLookup,
mRequest.originatingPendingIntent, mRequest.allowBackgroundActivityStart);
} finally {
onExecutionComplete();
}
}
private int startActivity(final ActivityRecord r, ActivityRecord sourceRecord,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
ActivityRecord[] outActivity, boolean restrictedBgActivity) {
int result = START_CANCELED;
final ActivityStack startedActivityStack;
try {
mService.mWindowManager.deferSurfaceLayout();
result = startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor,
startFlags, doResume, options, inTask, outActivity, restrictedBgActivity);
}
// …
}
private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
ActivityRecord[] outActivity, boolean restrictedBgActivity) {
// …
mRootActivityContainer.resumeFocusedStacksTopActivities();
}
}
接下里继续到RootActivityContainer;
/**
- Root node for activity containers.
- TODO: This class is mostly temporary to separate things out of ActivityStackSupervisor.java. The
- intention is to have this merged with RootWindowContainer.java as part of unifying the hierarchy.
- 看样子这个类后面可能会被合入到RootWindowContainer里,不重点分析;
*/
class RootActivityContainer {
boolean resumeFocusedStacksTopActivities(
ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {
if (targetStack != null && (targetStack.isTopStackOnDisplay() || getTopDisplayFocusedStack() == targetStack)) {
result = targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
}
}
}
7. ActivityStack源码分析
ActivityStack负责管理activity栈和activity的状态,包括根据activity栈的状态决定如何管理activity等,当然activity的启动也是由它来继续完成;
/**
- State and management of a single stack of activities.
*/
class ActivityStack extends ConfigurationContainer {
boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {
if (mInResumeTopActivity) {
// Don’t even start recursing.
return false;
}
boolean result = false;
try {
// Protect against recursion.
mInResumeTopActivity = true;
result = resumeTopActivityInnerLocked(prev, options);
}
}
private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
// …
if (next.attachedToProcess()) {
if (nextNext != next) {
// Do over!
mStackSupervisor.scheduleResumeTopActivities();
}
} else {
// Whoops, need to restart this activity!
mStackSupervisor.startSpecificActivityLocked(next, true, true);
}
}
}
8. StackSupervisor源码分析
// TODO: This class has become a dumping ground. Let’s
// - Move things relating to the hierarchy to RootWindowContainer
// - Move things relating to activity life cycles to maybe a new class called ActivityLifeCycler
// - Move interface things to ActivityTaskManagerService.
// - All other little things to other files.
// 看样子这部分代码后面也会被RootWindowContainer里面,后面Android源码分析可能要重点分析这个类了 😢
public class ActivityStackSupervisor implements RecentTasks.Callbacks {
void startSpecificActivityLocked(ActivityRecord r, boolean andResume, boolean checkConfig) {
// Is this activity’s application already running?
final WindowProcessController wpc =
mService.getProcessController(r.processName, r.info.applicationInfo.uid);
boolean knownToBeDead = false;
if (wpc != null && wpc.hasThread()) {
try {
// 重点分析
realStartActivityLocked(r, wpc, andResume, checkConfig);
return;
} catch (RemoteException e) {
Slog.w(TAG, "Exception when starting activity "
- r.intent.getComponent().flattenToShortString(), e);
}
// If a dead object exception was thrown – fall through to
// restart the application.
knownToBeDead = true;
}
}
boolean realStartActivityLocked(ActivityRecord r, WindowProcessController proc, boolean andResume, boolean checkConfig) {
// …
// Create activity launch transaction
final ClientTransaction clientTransaction = ClientTransaction.obtain( proc.getThread(), r.appToken);
// 重点,这里先记住它的callback是LaunchActivityItem
clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent),
System.identityHashCode®, r.info,
// TODO: Have this take the merged configuration instead of separate global
// and override configs.
mergedConfiguration.getGlobalConfiguration(),
mergedConfiguration.getOverrideConfiguration(), r.compat,
r.launchedFromPackage, task.voiceInteractor, proc.getReportedProcState(),
r.icicle, r.persistentState, results, newIntents,
dc.isNextTransitionForward(), proc.createProfilerInfoIfNeeded(),
r.assistToken));
// Schedule transaction. mService就是ActivityTaskManagerService
mService.getLifecycleManager().scheduleTransaction(clientTransaction);
}
}
以上代码分析出,启动activity被封装成transaction由ActivityTaskManagerService中的ClientLifecycleManager进程处理;
9. ClientLifecycleManager源码分析
class ClientLifecycleManager {
void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
final IApplicationThread client = transaction.getClient();
transaction.schedule();
if (!(client instanceof Binder)) {
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数初中级安卓工程师,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年最新Android移动开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频
如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注Android)
最后
文章不易,如果大家喜欢这篇文章,或者对你有帮助希望大家多多点赞转发关注哦。文章会持续更新的。绝对干货!!!
由于文章篇幅问题 查看详细文章以及获取学习笔记链接:GitHub
- Android进阶学习全套手册
关于实战,我想每一个做开发的都有话要说,对于小白而言,缺乏实战经验是通病,那么除了在实际工作过程当中,我们如何去更了解实战方面的内容呢?实际上,我们很有必要去看一些实战相关的电子书。目前,我手头上整理到的电子书还算比较全面,HTTP、自定义view、c++、MVP、Android源码设计模式、Android开发艺术探索、Java并发编程的艺术、Android基于Glide的二次封装、Android内存优化——常见内存泄露及优化方案、.Java编程思想 (第4版)等高级技术都囊括其中。
-
Android高级架构师进阶知识体系图
关于视频这块,我也是自己搜集了一些,都按照Android学习路线做了一个分类。按照Android学习路线一共有八个模块,其中视频都有对应,就是为了帮助大家系统的学习。接下来看一下导图和对应系统视频吧!!!
-
Android对标阿里P7学习视频
- BATJ大厂Android高频面试题
这个题库内容是比较多的,除了一些流行的热门技术面试题,如Kotlin,数据库,Java虚拟机面试题,数组,Framework ,混合跨平台开发,等
括其中。
[外链图片转存中…(img-d9T0bhIX-1711285151019)]
-
Android高级架构师进阶知识体系图
关于视频这块,我也是自己搜集了一些,都按照Android学习路线做了一个分类。按照Android学习路线一共有八个模块,其中视频都有对应,就是为了帮助大家系统的学习。接下来看一下导图和对应系统视频吧!!!
[外链图片转存中…(img-FC2mdQVu-1711285151019)] -
Android对标阿里P7学习视频
[外链图片转存中…(img-02y4lk4U-1711285151019)]
- BATJ大厂Android高频面试题
这个题库内容是比较多的,除了一些流行的热门技术面试题,如Kotlin,数据库,Java虚拟机面试题,数组,Framework ,混合跨平台开发,等