用虚拟机做网站服务器吗,wordpress房屋网站模板,郴州网站策划,菏泽哪家网站设计公司好前言 
在Android应用开发中#xff0c;启动流程是最基础也是最重要的机制之一。作为一名Android开发者#xff0c;理解应用启动的完整流程对于性能优化、问题排查和架构设计都至关重要。本系列文章将从最上层的Activity.startActivity()方法开始#xff0c;自上而下深入分析…前言 
在Android应用开发中启动流程是最基础也是最重要的机制之一。作为一名Android开发者理解应用启动的完整流程对于性能优化、问题排查和架构设计都至关重要。本系列文章将从最上层的Activity.startActivity()方法开始自上而下深入分析Android应用启动的完整流程。 
版本说明 
本文分析的代码基于Android 10API 29及以上版本。在Android 10中Google对Activity管理架构进行了重大调整 
Android 9及之前所有Activity相关功能由ActivityManagerServiceAMS统一管理Android 10及之后将Activity和Task管理功能拆分到新的ActivityTaskManagerServiceATMSAMS保留其他核心功能 
这个变更有以下背景 
解耦Activity管理与系统其他核心功能为多窗口、自由形态窗口等新特性提供更好的支持改善系统服务的模块化程度 
从Activity.startActivity开始 
让我们从最常见的场景出发——一个Activity启动另一个Activity。开发者最熟悉的调用方式就是startActivity()方法。 
Activity.startActivity() 
Override
public void startActivity(Intent intent) {this.startActivity(intent, null);
}这是Activity类中最简单的startActivity重载方法。可以看到它调用了另一个重载方法并传入了一个null的Bundle参数。 
Activity.startActivity(Intent, Bundle) 
public void startActivity(Intent intent, Nullable Bundle options) {if (options ! null) {startActivityForResult(intent, -1, options);} else {startActivityForResult(intent, -1);}
}这个方法检查是否有附加的options Bundle然后调用startActivityForResult()方法。注意这里传入的requestCode是-1表示我们不需要返回结果。 
Activity.startActivityForResult() 
public void startActivityForResult(RequiresPermission Intent intent, int requestCode,Nullable Bundle options) {// 检查是否有父Activityif (mParent  null) {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());}if (requestCode  0) {mStartedActivity  true;}cancelInputsAndStartExitTransition(options);} else {// 如果有父Activity则通过父Activity启动if (options ! null) {mParent.startActivityFromChild(this, intent, requestCode, options);} else {mParent.startActivityFromChild(this, intent, requestCode);}}
}这个方法有几个关键点 
首先检查是否有父Activity如果没有则继续流程否则通过父Activity启动使用Instrumentation的execStartActivity方法执行实际的启动操作如果有返回结果则通过ActivityThread发送结果处理Activity过渡动画 
Instrumentation.execStartActivity() 
public ActivityResult execStartActivity(Context who, IBinder contextThread, IBinder token, Activity target,Intent intent, int requestCode, Bundle options) {// 获取IApplicationThread对象IApplicationThread whoThread  (IApplicationThread) contextThread;// 记录来源Activityif (mActivityMonitors ! null) {synchronized (mSync) {final int N  mActivityMonitors.size();for (int i0; iN; i) {final ActivityMonitor am  mActivityMonitors.get(i);if (am.match(who, null, intent)) {am.mHits;if (am.isBlocking()) {return requestCode  0 ? am.getResult() : null;}break;}}}}try {intent.migrateExtraStreamToClipData();intent.prepareToLeaveProcess(who);// 关键调用通过ActivityTaskManager启动Activityint 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;
}这个方法做了以下几件事 
处理ActivityMonitor用于测试准备Intent数据通过ActivityTaskManager.getService()获取AMS的代理对象调用startActivity方法检查启动结果 
ActivityTaskManager.getService() 
public static IActivityTaskManager getService() {return IActivityTaskManagerSingleton.get();
}private static final SingletonIActivityTaskManager IActivityTaskManagerSingleton new SingletonIActivityTaskManager() {Overrideprotected IActivityTaskManager create() {// 获取ActivityTaskManagerService的代理对象final IBinder b  ServiceManager.getService(Context.ACTIVITY_TASK_SERVICE);return IActivityTaskManager.Stub.asInterface(b);}};这里通过Binder机制获取了系统服务ActivityTaskManagerService的代理对象。ATMS是Android 10之后从AMS中拆分出来的专门管理Activity和Task的服务。 
checkStartActivityResult() 
public static void checkStartActivityResult(int res, Object intent) {switch (res) {case ActivityManager.START_INTENT_NOT_RESOLVED:case ActivityManager.START_CLASS_NOT_FOUND:throw new ActivityNotFoundException(Unable to find explicit activity class  ((Intent)intent).getComponent().toShortString() ; have you declared this activity in your AndroidManifest.xml?);case ActivityManager.START_PERMISSION_DENIED:throw new SecurityException(Not allowed to start activity  ((Intent)intent).getComponent().toShortString());// 其他错误处理...}
}这个方法将ATMS返回的结果转换为相应的异常开发者常见的Activity未在Manifest中声明的错误就是在这里抛出的。 
流程概览 
到目前为止我们看到的调用流程如下 
Activity.startActivity()Activity.startActivity(Intent, Bundle)Activity.startActivityForResult()Instrumentation.execStartActivity()ActivityTaskManager.getService().startActivity() 
这个流程已经从应用进程进入了系统进程system_server后续的处理将在ATMS中进行。 
为什么需要Instrumentation 
你可能注意到在流程中有一个Instrumentation类参与其中。Instrumentation是Android测试框架的核心部分但它也参与正常的Activity启动流程。它的主要作用有 
提供一种监控系统与应用交互的机制在测试中可以替换组件行为在正常运行时作为Activity生命周期回调的中间层 
小结 
本文从最常用的Activity.startActivity()方法开始逐步深入分析了Android应用启动的前半段流程。我们了解到 
启动请求最终通过Instrumentation转发到系统服务通过Binder机制与系统服务ActivityTaskManagerService交互基本的错误检查和处理机制 附关键差异对比表 
组件/版本Android 9及之前Android 10及之后核心服务ActivityManagerService (AMS)ActivityTaskManagerService (ATMS)获取服务方式ActivityManager.getService()ActivityTaskManager.getService()管理范围包含Activity管理在内的所有功能专注Activity和Task管理Binder接口IActivityManagerIActivityTaskManager 
兼容性说明 
虽然架构发生了变化但上层API保持了兼容 
// 这两种写法在Android 10上效果相同但后者是推荐的新方式
startActivity(intent); // 仍然可用
ActivityTaskManager.getService().startActivity(...); // 新方式系统通过兼容层处理了API差异因此开发者无需修改现有代码。 
为什么需要拆分ATMS 
在Android 10的架构变更中拆分ATMS的主要考虑包括 职责单一化 AMS原本承担了太多职责内存管理、进程管理、Activity管理等拆分后ATMS专注于Activity和Task管理  多窗口支持 新的多窗口模式需要更复杂的Activity栈管理独立服务可以更灵活地实现这些功能  性能优化 减少AMS的锁竞争并行处理Activity相关操作  
代码路径差异 
在分析启动流程时需要注意不同版本的代码路径差异 
Android 9及之前 
// 老版本通过AMS启动Activity
ActivityManager.getService().startActivity(...)Android 10及之后 
// 新版本通过ATMS启动Activity
ActivityTaskManager.getService().startActivity(...)