2-APP启动过程2+ActivityThread源码分析
下面看下app初始化的主要步骤,app的初始化时从ActivityThread的main()开始的。首先,ActivityThread并不是一个线程,但它从main()跑起来后,它是程序运行的当前环境,它也就变成了整个app运行的主线程(UI线程)。
这个方法可以延伸出很多的知识点,也能发展出很多的面试问题
java程序是从main()开始的执行代码的,而Android app 从main()开始就显得有点难以理解但又有点理所应当,毕竟Android很长时间的第一语言是java
这里非重点的代码也不删除了,但只对关键的代码进行说明//程序启动
public static void main(String[] args) {Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ActivityThreadMain");// CloseGuard defaults to true and can be quite spammy. We// disable it here, but selectively enable it later (via// StrictMode) on debug builds, but using DropBox, not logs.CloseGuard.setEnabled(false);Environment.initForCurrentUser();// Set the reporter for event logging in libcoreEventLogger.setReporter(new EventLoggingReporter());// Make sure TrustedCertificateStore looks in the right place for CA certificatesfinal File configDir = Environment.getUserConfigDirectory(UserHandle.myUserId());TrustedCertificateStore.setDefaultUserDirectory(configDir);Process.setArgV0("<pre-initialized>");Looper.prepareMainLooper();//1,这行代码会创建一个Looper并保存到ThreadLocal中,创建一个Looper的同时也会1个消息队列MessageQueue和一个Thread// Find the value for {@link #PROC_START_SEQ_IDENT} if provided on the command line.// It will be in the format "seq=114"long startSeq = 0;if (args != null) {for (int i = args.length - 1; i >= 0; --i) {if (args[i] != null && args[i].startsWith(PROC_START_SEQ_IDENT)) {startSeq = Long.parseLong(args[i].substring(PROC_START_SEQ_IDENT.length()));}}}ActivityThread thread = new ActivityThread();//实例化ActivityThreadthread.attach(false, startSeq);//主要从这句拓展开来if (sMainThreadHandler == null) {sMainThreadHandler = thread.getHandler();//发送/调度Message的Handler出现了}if (false) {Looper.myLooper().setMessageLogging(newLogPrinter(Log.DEBUG, "ActivityThread"));}// End of event ActivityThreadMain.Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);Looper.loop();//持续循环,保证app处于活动状态throw new RuntimeException("Main thread loop unexpectedly exited");}
这里不对Looper,MessageQueue,Message,Handler等进行过多展开,留到后面分个章节详细分析,反正就是主线程有这些玩意保证了整个app事件的接收和处理。
主要是ActivityThread.attach()进行拓展分析。
1,ActivityThread.attach()private void attach(boolean system, long startSeq) {sCurrentActivityThread = this;mSystemThread = system;if (!system) {...final IActivityManager mgr = ActivityManager.getService();//这个看着有点眼熟,正是上一篇遇到过的ActivityManagerService的引用try {mgr.attachApplication(mAppThread, startSeq);//直接去AMS中找这个方法} catch (RemoteException ex) {throw ex.rethrowFromSystemServer();}}...
}2,ActivityManagerService.java@Overridepublic final void attachApplication(IApplicationThread thread, long startSeq) {synchronized (this) {int callingPid = Binder.getCallingPid();final int callingUid = Binder.getCallingUid();final long origId = Binder.clearCallingIdentity();attachApplicationLocked(thread, callingPid, callingUid, startSeq);//又跳到下面这个方法中了Binder.restoreCallingIdentity(origId);}}@GuardedBy("this")private final boolean attachApplicationLocked(IApplicationThread thread,int pid, int callingUid, long startSeq) {...ProcessRecord app;long startTime = SystemClock.uptimeMillis(); ...try {...thread.bindApplication(processName, appInfo, providers,//thread是ActivityThread中的类部类ApplicationThread的实例,相当于又回到了ActivityThreadapp.instr.mClass,profilerInfo, app.instr.mArguments,app.instr.mWatcher,app.instr.mUiAutomationConnection, testMode,mBinderTransactionTrackingEnabled, enableTrackAllocation,isRestrictedBackupMode || !normalMode, app.persistent,new Configuration(getGlobalConfiguration()), app.compat,getCommonServicesLocked(app.isolated),mCoreSettingsObserver.getCoreSettingsLocked(),buildSerial, isAutofillCompatEnabled);...} catch (Exception e) {...}// See if the top visible activity is waiting to run in this process... 上面是创建application,这里是创建activityif (normalMode) {try {if (mStackSupervisor.attachApplicationLocked(app)) {didSomething = true;}} catch (Exception e) {Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);badApp = true;}}...return true;}3,ActivithThread->ApplicationThread->bindApplication()public final void bindApplication(......) {AppBindData data = new AppBindData();data.processName = processName;data.appInfo = appInfo;data.providers = providers;data.instrumentationName = instrumentationName;data.instrumentationArgs = instrumentationArgs;data.instrumentationWatcher = instrumentationWatcher;data.instrumentationUiAutomationConnection = instrumentationUiConnection;data.debugMode = debugMode;data.enableBinderTracking = enableBinderTracking;data.trackAllocation = trackAllocation;data.restrictedBackupMode = isRestrictedBackupMode;data.persistent = persistent;data.config = config;data.compatInfo = compatInfo;data.initProfilerInfo = profilerInfo;data.buildSerial = buildSerial;data.autofillCompatibilityEnabled = autofillCompatibilityEnabled;sendMessage(H.BIND_APPLICATION, data);//通过main()中创建的handler去发送消息了,参数配置是真多,这个BIND_APPLICATION会调用handleBindApplication()}4, handleBindApplication()方法,但他最关键的作用就是创建了application(内部用了反射)
private void handleBindApplication(AppBindData data) {...Application app;final StrictMode.ThreadPolicy savedPolicy = StrictMode.allowThreadDiskWrites();final StrictMode.ThreadPolicy writesAllowedPolicy = StrictMode.getThreadPolicy();try {app = data.info.makeApplication(data.restrictedBackupMode, null);//反射创建Applicationapp.setAutofillCompatibilityEnabled(data.autofillCompatibilityEnabled);mInitialApplication = app;...try {mInstrumentation.onCreate(data.instrumentationArgs);}catch (Exception e) {throw new RuntimeException("Exception thrown in onCreate() of "+ data.instrumentationName + ": " + e.toString(), e);}try {mInstrumentation.callApplicationOnCreate(app);//application触发oncreate()方法} catch (Exception e) {...}} finally {...}...
}
经过不懈努力,App启动了一半,终于创建了Application并且执行了onCreate(),进程的相关设置已经完成,剩下就是activity的生成和调用。
1,ActivityManagerService.attachApplicationLocked()->mStackSupervisor.attachApplicationLocked(app)
ActivityStackSupervisor.javaboolean attachApplicationLocked(ProcessRecord app) throws RemoteException {final String processName = app.processName;boolean didSomething = false;for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {final ActivityDisplay display = mActivityDisplays.valueAt(displayNdx);for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {final ActivityStack stack = display.getChildAt(stackNdx);if (!isFocusedStack(stack)) {continue;}stack.getAllRunningVisibleActivitiesLocked(mTmpActivityList);final ActivityRecord top = stack.topRunningActivityLocked();final int size = mTmpActivityList.size();for (int i = 0; i < size; i++) {final ActivityRecord activity = mTmpActivityList.get(i);if (activity.app == null && app.uid == activity.info.applicationInfo.uid&& processName.equals(activity.processName)) {try {if (realStartActivityLocked(activity, app,top == activity /* andResume */, true /* checkConfig */)) {//最终执行的方法didSomething = true;}} catch (RemoteException e) {Slog.w(TAG, "Exception in new application when starting activity "+ top.intent.getComponent().flattenToShortString(), e);throw e;}}}}}if (!didSomething) {ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);}return didSomething;}2,接上面开始分析
final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app,boolean andResume, boolean checkConfig) throws RemoteException { // Create activity launch transaction.创建activity启动事务final ClientTransaction clientTransaction = ClientTransaction.obtain(app.thread,//传入app的线程,也就是ApplicationThreadr.appToken);clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent),System.identityHashCode(r), 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, app.repProcState, r.icicle,r.persistentState, results, newIntents, mService.isNextTransitionForward(),profilerInfo));...// Schedule transaction.mService.getLifecycleManager().scheduleTransaction(clientTransaction);//这是开始执行事务...return true;}
3,ClientLifecycleManager.scheduleTransaction
class ClientLifecycleManager {void scheduleTransaction(ClientTransaction transaction) throws RemoteException {final IApplicationThread client = transaction.getClient();transaction.schedule();if (!(client instanceof Binder)) {// If client is not an instance of Binder - it's a remote call and at this point it is// safe to recycle the object. All objects used for local calls will be recycled after// the transaction is executed on client in ActivityThread.transaction.recycle();}}...
}
4,执行的ApplicationThread中的ScheduleTransaction(),但方法中的实际实现却是在ActivityThread的父类中
class ApplicationThread extends IApplicationThread.Stub{@Overridepublic void scheduleTransaction(ClientTransaction transaction) throws RemoteException {ActivityThread.this.scheduleTransaction(transaction);//跳走了}
}public abstract class ClientTransactionHandler { //ActivityThread的父类void scheduleTransaction(ClientTransaction transaction) {transaction.preExecute(this);sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);}
}5,ActivityThread中接收消息并执行case EXECUTE_TRANSACTION:final ClientTransaction transaction = (ClientTransaction) msg.obj;mTransactionExecutor.execute(transaction);...break; 6,事务执行类
public class TransactionExecutor {private ClientTransactionHandler mTransactionHandler;private PendingTransactionActions mPendingActions = new PendingTransactionActions();private TransactionExecutorHelper mHelper = new TransactionExecutorHelper();public TransactionExecutor(ClientTransactionHandler clientTransactionHandler) {mTransactionHandler = clientTransactionHandler;}//从EXECUTE_TRANSACTION执行到这里public void execute(ClientTransaction transaction) {final IBinder token = transaction.getActivityToken();log("Start resolving transaction for client: " + mTransactionHandler + ", token: " + token);executeCallbacks(transaction);//执行executeLifecycleState(transaction);mPendingActions.clear();log("End resolving transaction");}public void executeCallbacks(ClientTransaction transaction) {final List<ClientTransactionItem> callbacks = transaction.getCallbacks();final IBinder token = transaction.getActivityToken();ActivityClientRecord r = mTransactionHandler.getActivityClient(token);final int size = callbacks.size();for (int i = 0; i < size; ++i) {//遍历事务所有的回调final ClientTransactionItem item = callbacks.get(i);log("Resolving callback: " + item);final int postExecutionState = item.getPostExecutionState();final int closestPreExecutionState = mHelper.getClosestPreExecutionState(r,item.getPostExecutionState());if (closestPreExecutionState != UNDEFINED) {cycleToPath(r, closestPreExecutionState);}item.execute(mTransactionHandler, token, mPendingActions);item.postExecute(mTransactionHandler, token, mPendingActions);if (r == null) {// Launch activity request will create an activity record.r = mTransactionHandler.getActivityClient(token);}if (postExecutionState != UNDEFINED && r != null) {// Skip the very last transition and perform it by explicit state request instead.final boolean shouldExcludeLastTransition =i == lastCallbackRequestingState && finalState == postExecutionState;cycleToPath(r, postExecutionState, shouldExcludeLastTransition);}}}}7,LaunchActivityItem继承自LaunchActivityItem,在AMS启动Activity事务时添加了回调@Overridepublic void execute(ClientTransactionHandler client, IBinder token,PendingTransactionActions pendingActions) {Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityStart");ActivityClientRecord r = new ActivityClientRecord(token, mIntent, mIdent, mInfo,mOverrideConfig, mCompatInfo, mReferrer, mVoiceInteractor, mState, mPersistentState,mPendingResults, mPendingNewIntents, mIsForward,mProfilerInfo, client);client.handleLaunchActivity(r, pendingActions, null /* customIntent */);//ActivityThread是ClientTransationHandler的实现类,于是,我们又跳回去了Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);} 8,ActivithThread.performLaunchActivity()private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {ActivityInfo aInfo = r.activityInfo;if (r.packageInfo == null) {r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,Context.CONTEXT_INCLUDE_CODE);}ComponentName component = r.intent.getComponent();if (component == null) {component = r.intent.resolveActivity(mInitialApplication.getPackageManager());r.intent.setComponent(component);}if (r.activityInfo.targetActivity != null) {component = new ComponentName(r.activityInfo.packageName,r.activityInfo.targetActivity);}ContextImpl appContext = createBaseContextForActivity(r);Activity activity = null;try {java.lang.ClassLoader cl = appContext.getClassLoader();//类加载器activity = mInstrumentation.newActivity(//Instrumentation完成activity的实例化,内部也是通过发射来生成activity的cl, component.getClassName(), r.intent);StrictMode.incrementExpectedActivityCount(activity.getClass());r.intent.setExtrasClassLoader(cl);r.intent.prepareToEnterProcess();if (r.state != null) {r.state.setClassLoader(cl);}} catch (Exception e) {}try {Application app = r.packageInfo.makeApplication(false, mInstrumentation);if (activity != null) {...activity.attach(appContext, this, getInstrumentation(), r.token,r.ident, app, r.intent, r.activityInfo, title, r.parent,r.embeddedID, r.lastNonConfigurationInstances, config,r.referrer, r.voiceInteractor, window, r.configCallback);//activity要完成PhoneWindow的实例化,为后续的布局显示做准备...if (r.isPersistable()) {mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);//mInstrumentation给activity执行oncreate()} else {mInstrumentation.callActivityOnCreate(activity, r.state);}...}r.setState(ON_CREATE);mActivities.put(r.token, r);} catch (SuperNotCalledException e) {throw e;} catch (Exception e) {}return activity;}
结合第一篇,App启动流程大体如下:
借用Android进阶解密的图,这个图相对来说符合当前源码的流程步骤
1,Launcher进程触发App跳转,同Binder通信告知AMS
2,AMS进过一系列转折后交给Zygote处理
3,Zygote通过fork操作孵化出新的进程,触发进程的ActivityThread的main()
4,ActivityThread.main()最终交给AMS依次生成Application和Activity,完成APP的启动
2-APP启动过程2+ActivityThread源码分析相关推荐
- Activity启动过程——10.0源码分析
对于一个activity,注意不是根activity,它的启动流程往往是通过创建intent,通过startActivity()的方式启动的,我们跟踪的就是安卓10.0这部分的启动流程. 在windo ...
- 【Android 安全】DEX 加密 ( Application 替换 | Android 应用启动原理 | ActivityThread 源码分析 )
文章目录 一.ActivityThread 源码分析 二.ActivityThread 部分代码示例 dex 解密时 , 需要将 代理 Application 替换为 真实 Application ; ...
- android源码学习- APP启动流程(android12源码)
前言: 百度一搜能找到很多讲APP启动流程的,但是往往要么就是太老旧(还是基于android6去分析的),要么就是不全(往往只讲了整个流程的一小部分).所以我结合网上现有的文章,以及源码的阅读和调试, ...
- modelandview使用过程_深入源码分析SpringMVC执行过程
本文主要讲解 SpringMVC 执行过程,并针对相关源码进行解析. 首先,让我们从 Spring MVC 的四大组件:前端控制器(DispatcherServlet).处理器映射器(HandlerM ...
- 详述 Spring MVC 启动流程及相关源码分析
文章目录 Web 应用部署初始化过程(Web Application Deployement) Spring MVC 启动过程 Listener 的初始化过程 Filter 的初始化 Servlet ...
- apollo源码启动服务,apollo源码分析
文章目录 1.下载APOLLO源码 2.执行Sql脚本 3.启动项目 3.1 启动ConfigServiceApplication 3.2 启动apollo-assembly 3.3 启动 apoll ...
- springboot启动过程_spring5/springboot2源码学习 -- spring boot 应用的启动过程
推荐阅读: Spring全家桶笔记:Spring+Spring Boot+Spring Cloud+Spring MVC 疫情期间"闭关修炼",吃透这本Java核心知识,跳槽面试不 ...
- ActivityThread 源码分析
目录 前言 分析 ActivityThread 的消息分发机制 总结 前言 前面分析了 Activity 的启动流程,ActivityThread 作为一个非常重要的角色发挥了非常重要的作用,为了对启 ...
- ActivityThread源码分析
1.问题 Android 11 Launcher启动流程分析说过,Android App进程的入口是"android.app.ActivityThread",那么: Activit ...
最新文章
- C++的 STL堆 实现获取中位数
- android camera(三):camera V4L2 FIMC
- 黄忠---忠心不二主
- C# WINFORM中的combobox.items.add实现像web开发那样,添加显示内容text和实际value值
- C# 取二位小数点(四舍五入)
- Java中的HashCode(1)之hash算法基本原理
- 功能强大的pdf控件,用户无需安装任何软件即可使用
- Linux elf文件分析
- 应用时标分离和动态逆方法设计飞行器的姿态控制系统(源代码)
- 中小学python教材电子版_【python爬虫】中小学人教版教材下载实践
- python3 安装 pillow报错
- 带上问题来看:主流技术Java、Python怎么?基本功又该怎么学?(什么是MySQL、Linux、算法?又该怎么用?)
- 2022-爬虫-Selenium-百度安全验证
- 指甲半月痕 血象和微量元素检查分析是否有贫血
- css——font 样式和对照表 颜色格式和颜色渐变
- nodejs--process
- 游戏编程模式 - 观察者模式
- Excel使用之时间相加减(精确到毫秒)
- 腾讯云域名如何绑定ip地址
- java tolist_java – Collectors.toList()返回什么类型的List?