App的启动流程

388 阅读7分钟

本文章仅供自己复习用,参考了这位大神的文章 

Android应用启动流程分析

下面正式开始文章

前言

一个android home界面可以看作是一个大的app,我们把他称作launcher,当我们点击一个app开始启动时,即调用startactivity方法。在了解启动流程之前,我们必须要知道的工具类有

  • Instrumention:负责管理ams
  • Activitythread: 应用的入口类,通过main函数开启looper的循环。activitythread所在的线程称为主线程(ui线程)
  • ams:android最核心的服务,负责四大组件的启动切换调度以及应用进程的管理和调度等工作,他本身是一个binder类的实现,应用进程通过binder机制调用系统服务
  • activitystarter:activity的启动工具,处理activity的各种flag
  • activitystackSupervisior:管理所有应用的activity栈,其中mFocusedStack就是当前应用的activity栈

binder机制

binder机制运用到的是c/s模式,client即我们的app进程,server就是zygote相关进程。zygote进程就相当于一个服务端,当客户端需要请求时,会首先把zygote进程fork出一个新zygote进程,然后开启我们的目标app

  • 本地代理与远程代理:一般从命名上可以分辨,xxNative是本地代理,xxProxy是在对方进程的binder代理
  • serviceManager的统一管理:ServiceManager管理所有的Android系统服务,有人把ServiceManager比喻成Binder机制中的DNS服务器,client端应用如果要使用系统服务,调用getSystemService接口,ServiceManager就会通过字符串形式的Binder名称找到并返回对应的服务的Binder对象。

服务端:Iactivitymanger--activitymanagerNative--AMS。

具体分析:AMN(ActivityManagerNative)作为服务器的stub(庄),其职责是对远程传递过来的数据进行反序列化

AMP(ActivityManagerProxy)作为服务启动代理,运行在客户端,负责将数据序列化传递给stub。在app中使用ams提供的功能,比如startActivity,是通过ams在客户端的代理AMP发起的

最下面一层是stub的具体实现---AMS

客户端:IApplicationThread--ApplicationThreadNative--ActivityThread

桩(stub):ApplicationNative

代理(Proxy):ApplicationThreadProxy,AMS通过客户端的ApplicationThreadProxy来处理实现实例化activity,调用oncreate等生命周期的函数的功能

最下面一层是桩(stub)的实现--applicationthread,他是activitythread的一个内部类,application负责响应系统进程发起的请求,而activitythread负责实际触发的业务逻辑。处理的请求要发送到activitythread的一个handler类上

通信过程分析

其具体的过程就是一个c/s模式的通信模型

  private void attach(boolean system, long startSeq) {
        sCurrentActivityThread = this;
        mSystemThread = system;
        if (!system) {
            android.ddm.DdmHandleAppName.setAppName("<pre-initialized>",
                                                    UserHandle.myUserId());
            RuntimeInit.setApplicationObject(mAppThread.asBinder());
            final IActivityManager mgr = ActivityManager.getService();
            try {
                mgr.attachApplication(mAppThread, startSeq);
            } catch (RemoteException ex) {
                throw ex.rethrowFromSystemServer();
            }

首先客户端中存在ams的代理类,通过该代理进行binder层次的信息传递,这就完成了从应用进程到系统进程,之后再从系统进程返回应用进程。而应用进程返回消息给系统进程,通过server端的proxy,调用bindapplicaiton方法调用返回的数据

private boolean attachApplicationLocked(@NonNull IApplicationThread thread,
            int pid, int callingUid, long startSeq) {

thread.bindApplication(processName, appInfo, providerList, null, profilerInfo,
                        null, null, null, testMode,
                        mBinderTransactionTrackingEnabled, enableTrackAllocation,
                        isRestrictedBackupMode || !normalMode, app.isPersistent(),
                        new Configuration(app.getWindowProcessController().getConfiguration()),
                        app.compat, getCommonServicesLocked(app.isolated),
                        mCoreSettingsObserver.getCoreSettingsLocked(),
                        buildSerial, autofillOptions, contentCaptureOptions,
                        app.mDisabledCompatChanges);

application的创建需要一些参数,由processrecord维护

  • AMS通过ProcessRecord来维护进程运行时的状态信息,需要将应用进程绑定到ProcessRecord才能开始一个Application的构建;
  • AMS维护的ProcessRecord这个数据结构,包含了进程运行时的信息,譬如应用进程的名称processName、解析AndroidManifest.xml得到的数据结构ApplicationInfo等,其中,要传递给应用进程的数据都是Parcelable类型的实例。

最后,在系统进程发送了binder通信之后,应用进程实现application的创建

ApplicationThread.onTransact()
└── ApplicationThread.bindApplication()
    └── ActivityThread.H.handleMessage(BIND_APPLICATION)
        └── ActivityThread.handleBindApplication()
            └── Application.onCreate()

这样就完成了application的创建。现在我们再回顾以下application创建经历了哪些类

应用进程to系统进程

ActivityThread.main()
└── ActivityThread.attach()
    └── IActivityManager.attachApplication(mAppThread)
        └── Binder.transact()

ActivityManagerService.onTransact()
└── ActivityManagerService.attachApplication(IApplicationThread thread)

系统进程to应用进程

ActivityManagerService.attachApplication()
└── ActivityManagerService.attachApplicationLocked()
    └── IApplicationThread.bindApplication(processName, appInfo ...)
        └── Binder.transact()

ApplicationThread.onTransact()
└── ApplicationThread.bindApplication()
    └── ActivityThread.H.handleMessage(BIND_APPLICATION)
        └── ActivityThread.handleBindApplication()
            └── Application.onCreate()

创建完application,即可以准备实现activity的创建,我们可以在后面再说,先继续谈一下activity中应用进程与系统进程的通信模型

在启动一个新的Activity时,AMS会将ActivityRecord的Token传递给应用进程,调用关系如下所示:

ActivityStackSupervisor.realStartActivityLocked(ActivityRecord, ...)
└── IApplicationThread.scheduleLaunchActivity(...token, ...)
    // 将ActivityRecord的Token跨进程传递给应用进程
    └── Binder.transact()

ActivityStackSupervisor.realStartActivityLocked()表示要启动一个Activity实例,ActivityRecord作为参数。从ActivityRecord中提取出Token对象,作为跨进程调用的参数,通过IApplicationThread.scheduleLaunchActivity()传递到应用进程。

在应用进程这一侧,会收到启动Activity的跨进程调用,触发以下函数的调用:

ApplicationThread.onTransact()
└── ApplicationThread.scheduleLaunchActivity(...token, ...)
    // token将被封装进ActivityClientRecord这个数据结构中
    └── ActivityThread.H.handleMessage()
        └── ActivityThread.handleLaunchActivity(LAUNCH_ACTIVITY)
            └── ActivityThread.performLaunchActivity(ActivityClientRecord, ...)
                // 从ActivityRecord取出token
                └── Activity.attch(...token, ...)

标准的Binder服务端处理流程,收到AMS传递过来的Token对象,进行一下数据封装(ActivityClientRecord),然后通过Handler抛出一个LAUNCH_ACTIVITY消息。这个消息显然也是抛到了应用进程的主线程去执行,所以ActivityThread.performLaunchActivity()函数会在主线程上执行,该函数从封装的数据结构ActivityClientRecord中取出Token对象,调用Activity.attach()函数,将其绑定到Activity上,如此一来,就建立应用进程的Activity与系统进程中ActivityRecord的关联。

系统进程维护的是ActivityRecord,应用进程维护的是Activity,两者之间的映射关系就是利用Token来维系的。

activity的启动流程

image

  • 当点击桌面app时,发起进程就是launcher所在进程,启动远程进程system_server
  • 在system_server进程中,会先调用process.start()方法,通过socket通信去通知zygote进程fork子进程,进程创建后将activitythread加载进去,执行activity的main方法
  • 在activitythread的main方法里,存在binder通信方的内部类applicationthread的实现,looper的循环,handler对象。而主要负责推进的是activitymanagerproxy通过binder通信对server端发送序列化之后的数据
  • 在system_server端,通过ams的attachapplication()向client端即Activitythread发送application创建数据,通过activitythread.handlebindapplication()创建application对象,并且attach(context)来绑定context,完成了activity创建前的准备
  • 在上一步执行的同时,在ams中会调用ActivitystackSupervisor类中的方法,这个类是activity的栈管理器,通过回调mStackSupervisor#attachApplicationLocked(),进而调用了ActivityThread#ApplicationThread#scheduleLaunchActivity() 方法,最终通过handler通信方式 ActivityThread#sendMessage(H.LAUNCH_ACTIVITY, r) 方法,最终走到了 ActivityThread#handleLaunchActivity() ,进而创建 Activity 对象
    然后调用 activity.attach() 方法,再调用 mInstrumentation#callActivityOnCreate() 执行 Activity#onCreate() 生命周期;

部分源码解析

在ams中调用了activitystater类中的方法

 @Override
    public 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, null,
                "startActivityAsUser");
    }

activitystarter又再向下调用了activitystacksupvisor类中的方法

    private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
            ActivityRecord[] outActivity) {

        ···
        if (mDoResume) {
            final ActivityRecord topTaskActivity =
                    mStartActivity.getTask().topRunningActivityLocked();
            if (!mTargetStack.isFocusable()
                    || (topTaskActivity != null && topTaskActivity.mTaskOverlay
                    && mStartActivity != topTaskActivity)) {
                ···
            } else {
               ···
                mSupervisor.resumeFocusedStackTopActivityLocked(mTargetStack, mStartActivity,
                        mOptions);
            }
        } else {
            ···
        }
        ···
    }

然后这两个类的方法最终回调到ams

   void startSpecificActivityLocked(ActivityRecord r,
            boolean andResume, boolean checkConfig) {
       ···
        if (app != null && app.thread != null) {
            try {
               ···
                // 如果进程已存在,则通知进程启动组件
                realStartActivityLocked(r, app, andResume, checkConfig);
                return;
            } catch (RemoteException e) {
                ···
            }
        }
        // 否则先将进程创建出来
        mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
                "activity", r.intent.getComponent(), false, false, true);
    }

在activitystackSupervisor类有一个方法 mStackSupervisor#attachApplicationLocked()调用了 ActivityThread#ApplicationThread#scheduleLaunchActivity()

   final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app,
            boolean andResume, boolean checkConfig) throws RemoteException {
        ···
        try {
            ···
            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);
             ···
        } catch (RemoteException e) {
            ···
        }
        ···
    }
    //ActivityStackSupervisor.java

        @Override
        public 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) {
            ···
            sendMessage(H.LAUNCH_ACTIVITY, r);
        }
        //ActivityThread#ApplicationThread.java

    private void sendMessage(int what, Object obj) {
        sendMessage(what, obj, 0, 0, false);
    }

    private void sendMessage(int what, Object obj, int arg1, int arg2, boolean async) {
        ···
        mH.sendMessage(msg);
    }
    //ActivityThread.java

最后执行activity的oncreate()方法

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

    private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
        ···
        Activity activity = null;
        try {
            //创建 Activity 对象
            java.lang.ClassLoader cl = appContext.getClassLoader();
            activity = mInstrumentation.newActivity(
                    cl, component.getClassName(), r.intent);
           ···
        } catch (Exception e) {
            ···
        }

        try {
            ···

            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#onCreate() 生命周期
                if (r.isPersistable()) {
                    mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
                } else {
                    mInstrumentation.callActivityOnCreate(activity, r.state);
                }
                ···
            }
            ···
        } catch (SuperNotCalledException e) {
            ···
        } catch (Exception e) {
            ···
    }