Android 应用程序启动过程

Activity启动过程可以分为两种:一种是根activity的启动过程,另一种是普通activity启动过程。根activity指的是应用程序启动的第一个activity,因此也可以理解为应用程序的启动过程。普通activity除根activity以外的其他activity。 - 根activity启动涉及4个进程:Zygote进程,Launcher进程、AMS所在的进程(systemServer进程)与应用程序进程。 - 普通activity启动只涉及AMS所在进程与应用程序进程。

根Activity启动流程

  • 点击桌面应用图标,Launcher进程将启动Activity的请求以Binder的方式发送给了AMS
  • AMS接收到启动请求后,判断根activity所需的应用程序进程是否存在并启动,不存在以Socket方式请求Zygote进程fork新进程。同时交付ActivityStarter处理IntentFlag等信息,然后再交给ActivityStackSupervisior/ActivityStack处理Activity进栈相关流程。
  • Zygote接收到新进程创建请求后fork出新进程。
  • 在新进程里创建ActivityThread对象,新创建的进程就是应用的主线程,在主线程里开启Looper消息循环,开始处理创建Activity
  • ActivityThread利用ClassLoader去加载Activity、创建Activity实例,并回调Activity的onCreate()方法。这样便完成了Activity的启动。

为什么zygote使用socket通信不使用binder通信

  1. zygoteservice manager 先启动;从这个意义上,他没有 service manager 可以注册,所以没法用 binder
  2. 因为他们两个都是 init 进程启动的,就算先启动 service manager,也不能保存 zygote 起来的时候 service manger 就已经初始化好了(这就需要额外的同步,太麻烦);
  3. 这个 socket 的所有者是 rootgroupsystem,只有系统权限的用户才能读写,这又多了一个安全保障(注意,这个 socketUnixsocket,不是 internet 域 socket);

AMS 大家族

  • ActivityManagerServices,简称AMS,服务端对象,负责系统中所有Activity的生命周期。
  • ActivityThreadApp的真正入口。当开启App之后,调用main()开始运行,开启消息循环队列,这就是传说的UI线程或者叫主线程。与ActivityManagerService一起完成Activity的管理工作。
  • ApplicationThread:用来实现ActivityManagerServieActivityThread之间的交互。在ActivityManagerSevice需要管理相关Application中的Activity的生命周期时,通过ApplicationThread的代理对象与ActivityThread通信。
  • ApplicationThreadProxy:是ApplicationThread在服务器端的代理,负责和客户端的ApplicationThread通信。AMS就是通过该代理与ActivityThread进行通信的。
  • Instrumentation:监控应用与系统相关的交互行为,每一个应用程序只有一个Instrumetation对象,每个Activity内都有一个对该对象的引用,Instrumentation可以理解为应用进程的管家,ActivityThread要创建或暂停某个Activity时,都需要通过Instrumentation来进行具体的操作。
  • ActivityStack:Activity在AMS的栈管理,用来记录经启动的Activity的先后关系,状态信息等。通过ActivtyStack决定是否需要启动新的进程。
  • ActivityRecordActivityStack的管理对象,每个Acivity在AMS对应一个ActivityRecord,来记录Activity状态以及其他的管理信息。其实就是服务器端的Activit对象的映像。
  • TaskRecord:AMS抽象出来的一个“任务”的概念,是记录ActivityRecord的栈,一个Task包含若干个ActivityRecordAMSTaskRecord确保Activity启动和退出的顺序。
  • ActivityStarter:Activity启动的控制器,处理Intent与Flag对Activity启动的影响,具体说来有:
    • 寻找符合启动条件的Activity,如果有多个,让用户选择;
    • 校验启动参数的合法性;
    • 返回int参数,代表Activity是否启动成功。
  • ActivityStackSupervisior:这个类的作用你从它的名字就可以看出来,它用来管理任务栈。

Activity 启动流程源码分析

Activity 调用startActivity最终都会调用startActivityForResult方法

public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,@Nullable Bundle options) {//判读当前Activity是否为空,为空调用Instrumentation的execStartActivity进行创建if (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());}......}

execStartActivity方法

public ActivityResult execStartActivity(Context who, IBinder contextThread, IBinder token, Activity target,Intent intent, int requestCode, Bundle options) {IApplicationThread whoThread = (IApplicationThread) contextThread;Uri referrer = target != null ? target.onProvideReferrer() : null;if (referrer != null) {intent.putExtra(Intent.EXTRA_REFERRER, referrer);}if (mActivityMonitors != null) {synchronized (mSync) {final int N = mActivityMonitors.size();for (int i=0; i<N; i++) {final ActivityMonitor am = mActivityMonitors.get(i);ActivityResult result = null;if (am.ignoreMatchingSpecificIntents()) {result = am.onStartActivity(intent);}if (result != null) {am.mHits++;return result;} else if (am.match(who, null, intent)) {am.mHits++;if (am.isBlocking()) {return requestCode >= 0 ? am.getResult() : null;}break;}}}}try {intent.migrateExtraStreamToClipData();intent.prepareToLeaveProcess(who);int result = ActivityManager.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;}

启动Activity最终调用的是ActivityManager.getService().startActivity方法,而ActivityManager.getService()返回的是IActivityManager对象,它是一个Binder对象。 ActivityManagerService继承自IActivityManager.Stub对象。 getService方法如下:

public static IActivityManager getService() {//获取IActivityManagerSingleton实例return IActivityManagerSingleton.get();}
//创建IActivityManagerSingleton实例对象private static final Singleton<IActivityManager> IActivityManagerSingleton =new Singleton<IActivityManager>() {@Overrideprotected IActivityManager create() {final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);final IActivityManager am = //将服务端对象转换成客户端所需的AIDL接口对象,由于ActivityManagerService继承自IActivityManager.Stub对象。所以这里就返回了ActivityManagerService对象实例IActivityManager.Stub.asInterface(b);return am;}};

所以ActivityManager.getService().startActivity方法实质上调用的是ActivityManagerService的startActivity方法。 checkStartActivityResult方法是用来检查Activity启动的结果,比如没有在AndroidManifest.xml中注册这个Activity实例对象。

public static void checkStartActivityResult(int res, Object intent) {if (!ActivityManager.isStartResultFatalError(res)) {return;}switch (res) {case ActivityManager.START_INTENT_NOT_RESOLVED:case ActivityManager.START_CLASS_NOT_FOUND:if (intent instanceof Intent && ((Intent)intent).getComponent() != null)throw new ActivityNotFoundException("Unable to find explicit activity class "+ ((Intent)intent).getComponent().toShortString()+ "; have you declared this activity in your AndroidManifest.xml?");throw new ActivityNotFoundException("No Activity found to handle " + intent);case ActivityManager.START_PERMISSION_DENIED:throw new SecurityException("Not allowed to start activity "+ intent);case ActivityManager.START_FORWARD_AND_REQUEST_CONFLICT:throw new AndroidRuntimeException("FORWARD_RESULT_FLAG used while also requesting a result");case ActivityManager.START_NOT_ACTIVITY:throw new IllegalArgumentException("PendingIntent is not an activity");case ActivityManager.START_NOT_VOICE_COMPATIBLE:throw new SecurityException("Starting under voice control not allowed for: " + intent);case ActivityManager.START_VOICE_NOT_ACTIVE_SESSION:throw new IllegalStateException("Session calling startVoiceActivity does not match active session");case ActivityManager.START_VOICE_HIDDEN_SESSION:throw new IllegalStateException("Cannot start voice activity on a hidden session");case ActivityManager.START_ASSISTANT_NOT_ACTIVE_SESSION:throw new IllegalStateException("Session calling startAssistantActivity does not match active session");case ActivityManager.START_ASSISTANT_HIDDEN_SESSION:throw new IllegalStateException("Cannot start assistant activity on a hidden session");case ActivityManager.START_CANCELED:throw new AndroidRuntimeException("Activity could not be started for "+ intent);default:throw new AndroidRuntimeException("Unknown error code "+ res + " when starting " + intent);}}

ActivityManagerService的startActivity方法。

@Overridepublic 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());}@Overridepublic final int startActivityAsUser(IApplicationThread caller, String callingPackage,Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {enforceNotIsolatedCaller("startActivity");userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),userId, false, ALLOW_FULL_ONLY, "startActivity", null);// TODO: Switch to user app stacks here.return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,profilerInfo, null, null, bOptions, false, userId, null, "startActivityAsUser");}

调用了startActivityMayWait方法进入到了ActivityStarter类中,而startActivityMayWait中又调用了startActivityLocked方法

final int startActivityMayWait(IApplicationThread caller, int callingUid,String callingPackage, Intent intent, String resolvedType,IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,IBinder resultTo, String resultWho, int requestCode, int startFlags,ProfilerInfo profilerInfo, WaitResult outResult,Configuration globalConfig, Bundle bOptions, boolean ignoreTargetSecurity, int userId,TaskRecord inTask, String reason) {final ActivityRecord[] outRecord = new ActivityRecord[1];int res = startActivityLocked(caller, intent, ephemeralIntent, resolvedType,aInfo, rInfo, voiceSession, voiceInteractor,resultTo, resultWho, requestCode, callingPid,callingUid, callingPackage, realCallingPid, realCallingUid, startFlags,options, ignoreTargetSecurity, componentSpecified, outRecord, inTask,reason);
}

ActivityStarter类中startActivityMayWait—>startActivityLocked->startActivity->startActivityUnchecked然后调用resumeFocusedStackTopActivityLocked方法进入到了ActivityStackSupervisior类中。

boolean resumeFocusedStackTopActivityLocked(ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {if (!readyToResume()) {return false;}if (targetStack != null && isFocusedStack(targetStack)) {//当期ActivityStack不为空就调用resumeTopActivityUncheckedLocked方法return targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);}final ActivityRecord r = mFocusedStack.topRunningActivityLocked();if (r == null || r.state != RESUMED) {mFocusedStack.resumeTopActivityUncheckedLocked(null, null);} else if (r.state == RESUMED) {// Kick off any lingering app transitions form the MoveTaskToFront operation.mFocusedStack.executeAppTransition(targetOptions);}return false;}

当期ActivityStack不为空就调用resumeTopActivityUncheckedLocked方法,在这个方法中又调用了resumeTopActivityInnerLocked方法 mStackSupervisor.startSpecificActivityLocked(next, true, true);

void startSpecificActivityLocked(ActivityRecord r,boolean andResume, boolean checkConfig) {// Is this activity's application already running?ProcessRecord app = mService.getProcessRecordLocked(r.processName,r.info.applicationInfo.uid, true);r.getStack().setLaunchTime(r);if (app != null && app.thread != null) {try {if ((r.info.flags&ActivityInfo.FLAG_MULTIPROCESS) == 0|| !"android".equals(r.info.packageName)) {app.addPackage(r.info.packageName, r.info.applicationInfo.versionCode,mService.mProcessStats);}realStartActivityLocked(r, app, andResume, checkConfig);return;} catch (RemoteException e) {Slog.w(TAG, "Exception when starting activity "+ r.intent.getComponent().flattenToShortString(), e);}}

内部调用realStartActivityLocked开始真正的启动Activity

final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app,boolean andResume, boolean checkConfig) throws RemoteException {......app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,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, !andResume,mService.isNextTransitionForward(), profilerInfo);
.....
}

这里的app.thread.就是IApplicationThread,它继承自IInterface,是一个Binder对象,包含大量启动与停止Activity接口,还包含服务。 private class ApplicationThread extends IApplicationThread.Stub ActivityThread内部类ApplicationThread继承IApplicationThread.Stub对象,所以app.thread.scheduleLaunchActivity方法调用实质就是调用ApplicationThreadscheduleLaunchActivity方法。

@Overridepublic final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,ActivityInfo info, Configuration curConfig, Configuration overrideConfig,CompatibilityInfo compatInfo, String referrer, IVoiceInteractor voiceInteractor,int procState, Bundle state, PersistableBundle persistentState,List<ResultInfo> pendingResults, List<ReferrerIntent> pendingNewIntents,boolean notResumed, boolean isForward, ProfilerInfo profilerInfo) {updateProcessState(procState, false);ActivityClientRecord r = new ActivityClientRecord();r.token = token;r.ident = ident;r.intent = intent;r.referrer = referrer;r.voiceInteractor = voiceInteractor;r.activityInfo = info;r.compatInfo = compatInfo;r.state = state;r.persistentState = persistentState;r.pendingResults = pendingResults;r.pendingIntents = pendingNewIntents;r.startsNotResumed = notResumed;r.isForward = isForward;r.profilerInfo = profilerInfo;r.overrideConfig = overrideConfig;updatePendingConfiguration(curConfig);sendMessage(H.LAUNCH_ACTIVITY, r);}

scheduleLaunchActivity做的事很简单,就是通过handler发送一个启动Activity的消息。

case LAUNCH_ACTIVITY: {Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStart");final ActivityClientRecord r = (ActivityClientRecord) msg.obj;r.packageInfo = getPackageInfoNoCheck(r.activityInfo.applicationInfo, r.compatInfo);handleLaunchActivity(r, null, "LAUNCH_ACTIVITY");Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);} break;

然后调用handleLaunchActivity来处理

private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) {Activity a = performLaunchActivity(r, customIntent);......
}

内部又调用performLaunchActivity来创建Activity 首先获取Activity的组件信息

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);}

然后通过Instrumentation.newActivity使用ClassLoader类加载器去创建Activity实例对象

try {java.lang.ClassLoader cl = appContext.getClassLoader();activity = mInstrumentation.newActivity(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) {if (!mInstrumentation.onException(activity, e)) {throw new RuntimeException("Unable to instantiate activity " + component+ ": " + e.toString(), e);}}

再通过Application app = r.packageInfo.makeApplication(false, mInstrumentation);创建Application对象实例,方法内部进行判断是否已经创建,创建过后就不会再次创建。 创建ContextImpl对象并通过Activity的attach方法进行一些重要的数据初始化操作,ContextImpl是一种重要的数据结构,是Context的具体实现,Context的大部分逻辑都是通过ContextImpl来完成的。它是通过Activity的attach方法进行与Activity关联的。

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的onCreate方法完成Activity的创建

activity.mCalled = false;if (r.isPersistable()) {mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);} else {mInstrumentation.callActivityOnCreate(activity, r.state);}}
public void callActivityOnCreate(Activity activity, Bundle icicle,PersistableBundle persistentState) {prePerformCreate(activity);activity.performCreate(icicle, persistentState);postPerformCreate(activity);
}

ActivityonCreate方法

final void performCreate(Bundle icicle, PersistableBundle persistentState) {mCanEnterPictureInPicture = true;restoreHasCurrentPermissionRequest(icicle);if (persistentState != null) {onCreate(icicle, persistentState);} else {onCreate(icicle);}mActivityTransitionState.readState(icicle);mVisibleFromClient = !mWindow.getWindowStyle().getBoolean(com.android.internal.R.styleable.Window_windowNoDisplay, false);mFragments.dispatchActivityCreated();mActivityTransitionState.setEnterActivityOptions(this, getActivityOptions());}

activity 生命周期_Activity 源码解析相关推荐

  1. php 变量存活期,php 变量生命周期:PHP源码分析-PHP的生_php

    php的最多的两种运行模式是web模式.CLI模式. 无论哪种模式,PHP工作原理都是一样的,作为一种SAPI运行. 1.当我们在终端敲入php这个命令的时候,它使用的是CLI. 它就像一个web服务 ...

  2. Spring IOC和Bean生命周期以及源码分析

    这篇文章主要讲解 IOC 容器的创建过程,让大家对整体有一个全局的认识,文章目录如图: 1. 基础知识 1.1 什么是 Spring IOC ? IOC 不是一种技术,只是一种思想,一个重要的面向对象 ...

  3. Spring5源码 - 07 Spring Bean 生命周期流程 源码解读02

    文章目录 Pre 通俗流程 finishBeanFactoryInitialization Pre Spring5源码 - 06 Spring Bean 生命周期流程 概述 01 接上文 通俗流程 下 ...

  4. Activity与调用线(三):Activity生命周期源码解析

    前言 很高兴遇见你~ 欢迎阅读我的文章. 关于Activity生命周期的文章,网络上真的很多,有很多的博客也都讲得相当不错,可见Activity的重要性是非常高的.事实上,我猜测每个android开发 ...

  5. Android全面解析之Activity生命周期

    前言 很高兴遇见你~ 欢迎阅读我的文章. 关于Activity生命周期的文章,网络上真的很多,有很多的博客也都讲得相当不错,可见Activity的重要性是非常高的.事实上,我猜测每个android开发 ...

  6. framework之Activity 生命周期解析(基于Android11源码)

    引言 上一篇讲了Activity的创建过程(没看过的小伙伴移步 点我前往).由于篇幅的问题,只分析到OnCreate周期,那这一篇就接着讲余下部分的周期. 在高版本上,activity的周期都是以事务 ...

  7. Glide 源码解析之监听生命周期

    code小生 一个专注大前端领域的技术平台公众号回复Android加入安卓技术群 作者:断了谁的弦 链接:https://www.jianshu.com/p/1169a91342a9 声明:本文已获断 ...

  8. 从源码看 Activity 生命周期(上篇)

    本文是我的 AOSP 系列 第六篇文章,往期目录如下: Java 世界的盘古和女娲 -- Zygote Zygote家的大儿子 -- SystemServer Android 世界中,谁喊醒了 Zyg ...

  9. Spring Bean的生命周期以及IOC源码解析

    IOC源码这一块太多只能讲个大概吧,建议还是去买本Spring IOC源码解析的书来看比较好,我也是自己看源代码以及视频整理的笔记 Bean的生命周期大概可以分为四个阶段,具体的等会再说,先看看IOC ...

最新文章

  1. AJPFX实例集合嵌套之ArrayList嵌套ArrayList
  2. 数字0-9的数量(51Nod-1042)
  3. 为什么python如此火爆_Python为何如此火爆?
  4. Python中常见的字符串小笔试题
  5. 分享一个前辈的NPOIhelper
  6. getResource()和getResourceAsStream以及路径问题
  7. 数据分析工作到底在做什么
  8. Navicat 8 用户与注册码
  9. 【git】git+码云上传代码
  10. 【独行秀才】macOS Big Sur 11.6正式版(20G165)原版镜像
  11. STC8A8K64D4(51系列单片机)printf打印数据异常的问题
  12. 计算机中电容状态表示什么,电脑主板电容坏了的表现有哪些?
  13. 圆柱体的投影特点_圆柱体三面投影作图方法分析
  14. Hadoop HA (四) --------- YARN-HA 配置
  15. python安装不了是什么问题_python为什么安装了运行不了?
  16. 中国线缆产业电商的拓荒者 专访缆360 CEO胡德良
  17. 数字IC手撕代码--交通灯
  18. 520送什么比较特别、送礼物合集
  19. html5基础考试选择题,HTML5 基础测试题
  20. 技术是一种加速器 但重要的不是技术

热门文章

  1. 服务器文件地址怎么写,服务器里的文件链接地址怎么写
  2. mysql和oracle用户管理_五种Oracle用户的授权与管理
  3. python打印不同颜色的字_Python 根据日志级别打印不同颜色的日志的方法示例
  4. 基于element ui的收起展开检索条件效果
  5. supermap iserver端口介绍
  6. 新微擎 v1.7.9 图文回复 标题emoji
  7. python快速入门 数据输出和基本类型 常用的循环遍历等
  8. 用8张图理解Java
  9. 修改linux终端的提示字符
  10. 验证字符串是否回文 Valid Palindrome