点击联系客服
客服QQ: 客服微信:

珠海老站长

查看: 399|回复: 50

面试一定要问 敲重点!能告诉我Android应用程序启动过程和源代码吗?

[复制链接]

1

主题

1

帖子

-7

积分

限制会员

积分
-7
发表于 2021-9-30 07:42:08 | 显示全部楼层 |阅读模式
一、写在前面

开始之前,您需要知道以下事项:

http://www  . Sina.com/3358 www  . Sina.com/3358 www  . Sina.com/3358 www  . Sina.com/

主要类介绍

有一份编译好的 Android  源码,现在的 AS  基本能满足,动手跟着步骤走,理解更深刻:AMS是Android最核心的服务之一,主要负责系统四个主要组件的启动、转换、调度和应用进程的管理和调度,作用类似于操作系统的进程管理和调度模块,是Binder实现类。对 Binder  机制有一定的了解:应用的门户类,系统通过调用main函数打开消息循环队列。具有ActivityThread的线程称为应用程序的主线程(UI线程)。本文基于 API  26,用什么版本的源码并不重要,大体的流程并无本质上的区别:监视应用程序和系统之间的交互,包装ActivityManagerService调用,某些插件方案通过hook实现。从用户手指触摸点击桌面图标到 Activity  启动:用于处理启动活动的各种flag的活动启动工具类。ActivityManagerService:管理所有应用的活动堆栈。其中mFocusedStack是当前应用的Activity堆栈。

应用进程简介

大多数情况下,每个Android应用程序都在自己的Linux进程中运行。需要运行部分应用代码时,将创建应用进程,并继续运行,直到不再需要,需要回收内存供其他应用程序使用。应用进程的生命周期不是由应用本身直接控制的,而是系统正在运行的应用部分、这些内容对用户的重要性以及系统中可用的内存总量等多种因素的组合来确定。这是Android非常独特的基本功能。如果应用组件启动,但应用时没有其他组件运行,则Android系统将使用单个执行线程,在应用时启动新的Linux进程。默认情况下,同一个应用程序的所有组件都在同一个进程和线程(称为“主”线程)上运行。如果应用组件已启动,并且应用进程已存在(因为该应用的其他组件存在),则该组件将在进程内启动,并使用相同的执行线程。但是,您可以安排应用程序的其他组件在单独的进程中运行,并为所有进程创建其他线程。每个应用进程对应于一个Sandbox沙箱,Android通过为每个应用程序分配一个Uid,具有与Linux系统上的用户ID不同的UID。
可以将每个应用理解为一个 User ,只能对其目录下的内容具有访问和读写权限。
  • Android 利用远程过程调用 (RPC) 提供了一种进程间通信 (IPC) 机制,在此机制中,系统会(在其他进程中)远程执行由 Activity 或其他应用组件调用的方法,并将所有结果返回给调用方。因此,您需将方法调用及其数据分解至操作系统可识别的程度,并将其从本地进程和地址空间传输至远程进程和地址空间,然后在远程进程中重新组装并执行该调用。然后,返回值将沿相反方向传输回来。Android 提供执行这些 IPC 事务所需的全部代码,因此您只需集中精力定义和实现 RPC 编程接口。

    下面这张图可以补充理解一下进程的概念:

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-L0wkWHQT-1632919531109)(//upload-images.jianshu.io/upload_images/1856419-c04a4f0fb34a7926.png?imageMogr2/auto-orient/strip|imageView2/2/w/678/format/webp)]

    二、流程分析
    先来一张流程简图:

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dv73EZ0Y-1632919531112)(//upload-images.jianshu.io/upload_images/1856419-234677e55f408b9c.png?imageMogr2/auto-orient/strip|imageView2/2/w/1106/format/webp)]

    下面是流程详细图,带你看完整个启动流程及其所涉及到的类:

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4geW8WPo-1632919531115)(//upload-images.jianshu.io/upload_images/1856419-f334b3f2122b430c.png?imageMogr2/auto-orient/strip|imageView2/2/w/917/format/webp)]

    下面补充一张 Gityuan 大神的系统启动架构图帮助理解,其实只要看看这张图的上半部分就足够了:

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3MMQZcf5-1632919531121)(//upload-images.jianshu.io/upload_images/1856419-88d738be242f6233.jpg?imageMogr2/auto-orient/strip|imageView2/2/w/1200/format/webp)]

    三、概述
    简单地讲,从 用户手指触摸点击桌面图标到 Activity启动 可以用下面 4 步概括:


    [ol]
  • 当点击桌面 App 的时候,发起进程就是 Launcher 所在的进程,启动远程进程,利用 Binder 发送消息给 system_server 进程;[/ol]


  • 在 system_server 中,启动进程的操作会先调用
    ActivityManagerService#startProcessLocked() 方法,该方法内部调用 Process.start(android.app.ActivityThread);而后通过 socket 通信告知 Zygote 进程 fork 子进程,即 app 进程。进程创建后将 ActivityThread 加载进去,执行 ActivityThread#main()方法;[/ol]


  • 在 app 进程中,main() 方法会实例化 ActivityThread,同时创建 ApplicationThread,Looper,Handler 对象,调用 ActivityThread#attach(false) 方法进行 Binder 通信,方法里面调用 ActivityManagerService#attachApplication(mAppThread) 方法,将 thread 信息告知 ActivityManagerService , 接着 Looper 启动循环;[/ol]


  • 回到 system_server 中,ActivityManagerService#attachApplication(mAppThread) 方法内部调用了 thread#bindApplication() 和 mStackSupervisor#attachApplicationLocked() 我们依次讲解这两个方法;
    4.1 thread#bindApplication() 方法调用了 ActivityThread#sendMessage(H.BIND_APPLICATION, data) 方法,最终走到了 ActivityThread#handleBindApplication(),进而创建 Application 对象,然后调用 Application#attach(context) 来绑定 Context ,创建完 Application 对象后便是调用 mInstrumentation#callApplicationOnCreate() 执行 Application#onCreate() 生命周期;
    4.2 mStackSupervisor#attachApplicationLocked() 方法中调用 app#thread#scheduleLaunchActivity() 即 ActivityThread#ApplicationThread#scheduleLaunchActivity() 方法,进而通过 ActivityThread#sendMessage(H.LAUNCH_ACTIVITY, r) 方法,最终走到了 ActivityThread#handleLaunchActivity() ,进而创建 Activity 对象,然后调用 activity.attach() 方法,再调用 mInstrumentation#callActivityOnCreate() 执行 Activity#onCreate() 生命周期;[/ol]

    四、源码调用探究
    对应本文第一张流程图的每一个步骤,下面逐步来看看源码是怎么调用的:

    STEP 1
    用户点击 app 图标;

    STEP 2
    Launcher 捕获点击事件,调用 Activity#startActivity();

    STEP 3
    Activity#startActivity() 调用 Instrumentation;


    Activity.java


        @Override
        public void startActivity(Intent intent) {
            this.startActivity(intent, null);
        }
        @Override
        public void startActivity(Intent intent, @Nullable Bundle options) {
            if (options != null) {
                startActivityForResult(intent, -1, options);
            } else {
                // Note we want to go through this call for compatibility with
                // applications that may have overridden the method.
                startActivityForResult(intent, -1);
            }
        }
        public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
                @Nullable Bundle options) {
            if (mParent == null) {
                options = transferSpringboardActivityOptions(options);
                Instrumentation.ActivityResult ar =
                    mInstrumentation.execStartActivity(
                        this, mMainThread.getApplicationThread(), mToken, this,
                        intent, requestCode, options);
                ···
            } else {
                ···
            }
        }

    STEP 4
    Instrumentation 通过 Binder 通信发送消息给 system_server 进程,具体 调用 ActivityManager#getService()#startActivity() ,ActivityManager#getService() 的具体实现是 ActivityManagerService ;


    Instrumentation.java


        public ActivityResult execStartActivity(
                Context who, IBinder contextThread, IBinder token, Activity target,
                Intent intent, int requestCode, Bundle options) {
            ···
            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;
        }


    ActivityManager.java


        public static IActivityManager getService() {
            return IActivityManagerSingleton.get();
        }
        private static final Singleton[I] IActivityManagerSingleton =
                new Singleton[I]() {
                    @Override
                    protected IActivityManager create() {
                        final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);
                        final IActivityManager am = IActivityManager.Stub.asInterface(b);
                        return am;
                    }
                };

    STEP 5
    ActivityManagerService 调用 ActivityStarter;


    ActivityManagerService.java


        @Override
        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());
        }
        @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");
        }

    STEP 6
    ActivityStarter 调用 ActivityStackSupervisor;

        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,
                IActivityContainer iContainer, TaskRecord inTask, String reason) {
            ···
                int res = startActivityLocked(caller, intent, ephemeralIntent, resolvedType,
                        aInfo, rInfo, voiceSession, voiceInteractor,
                        resultTo, resultWho, requestCode, callingPid,
                        callingUid, callingPackage, realCallingPid, realCallingUid, startFlags,
                        options, ignoreTargetSecurity, componentSpecified, outRecord, container,
                        inTask, reason);
            ···
        }
        int startActivityLocked(IApplicationThread caller, Intent intent, Intent ephemeralIntent,
                String resolvedType, ActivityInfo aInfo, ResolveInfo rInfo,
                IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
                IBinder resultTo, String resultWho, int requestCode, int callingPid, int callingUid,
                String callingPackage, int realCallingPid, int realCallingUid, int startFlags,
                ActivityOptions options, boolean ignoreTargetSecurity, boolean componentSpecified,
                ActivityRecord[] outActivity, ActivityStackSupervisor.ActivityContainer container,
                TaskRecord inTask, String reason) {
            ···
            mLastStartActivityResult = startActivity(caller, intent, ephemeralIntent, resolvedType,
                    aInfo, rInfo, voiceSession, voiceInteractor, resultTo, resultWho, requestCode,
                    callingPid, callingUid, callingPackage, realCallingPid, realCallingUid, startFlags,
                    options, ignoreTargetSecurity, componentSpecified, mLastStartActivityRecord,
                    container, inTask);
           ···
            return mLastStartActivityResult;
        }
        private int startActivity(IApplicationThread caller, Intent intent, Intent ephemeralIntent,
                String resolvedType, ActivityInfo aInfo, ResolveInfo rInfo,
                IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
                IBinder resultTo, String resultWho, int requestCode, int callingPid, int callingUid,
                String callingPackage, int realCallingPid, int realCallingUid, int startFlags,
                ActivityOptions options, boolean ignoreTargetSecurity, boolean componentSpecified,
                ActivityRecord[] outActivity, ActivityStackSupervisor.ActivityContainer container,
                TaskRecord inTask) {
            ···
            return startActivity(r, sourceRecord, voiceSession, voiceInteractor, startFlags, true,
                    options, inTask, outActivity);
        }
        private int startActivity(final ActivityRecord r, ActivityRecord sourceRecord,
                IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
                int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
                ActivityRecord[] outActivity) {
            ···
            try {
                mService.mWindowManager.deferSurfaceLayout();
                result = startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor,
                        startFlags, doResume, options, inTask, outActivity);
            } finally {
               ···
            }
            ···
        }
        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 {
                ···
            }
            ···
        }

    STEP 7
    ActivityStackSupervisor 调用 ActivityStack;

        boolean resumeFocusedStackTopActivityLocked(
                ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {
            if (targetStack != null && isFocusedStack(targetStack)) {
                return targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
            }
           ···
            return false;
        }

    STEP 8
    ActivityStack 回调到 ActivityStackSupervisor ;

        boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {
           ···
            try {
                ···
                result = resumeTopActivityInnerLocked(prev, options);
            } finally {
                ···
            }
            ···
            return result;
        }
        private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
            ···
            if (next.app != null && next.app.thread != null) {
               ···
            } else {
                ···
                mStackSupervisor.startSpecificActivityLocked(next, true, true);
            }
            ···
        }

    STEP 9
    ActivityStackSupervisor 回调到 ActivityManagerService,这里会判断要启动 App 的进程是否存在,存在则通知进程启动 Activity,否则就先将进程创建出来;

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

    STEP 10
    接着我们来看看进程尚未创建的情况,我们看到这里最终调用的是 Process#start() 来启动进程;


    ActivityManagerService.java


        final ProcessRecord startProcessLocked(String processName,
                ApplicationInfo info, boolean knownToBeDead, int intentFlags,
                String hostingType, ComponentName hostingName, boolean allowWhileBooting,
                boolean isolated, boolean keepIfLarge) {
            return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
                    hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
                    null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
                    null /* crashHandler */);
        }
        final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
                boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
                boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
                String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
            ···
            startProcessLocked(
                    app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
            ···
        }
        private final void startProcessLocked(ProcessRecord app, String hostingType,
                String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
            ···
                if (entryPoint == null) entryPoint = "android.app.ActivityThread";
                Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
                        app.processName);
                checkTime(startTime, "startProcess: asking zygote to start proc");
                ProcessStartResult startResult;
                if (hostingType.equals("webview_service")) {
                    ···
                } else {
                    startResult = Process.start(entryPoint,
                            app.processName, uid, uid, gids, debugFlags, mountExternal,
                            app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
                            app.info.dataDir, invokeWith, entryPointArgs);
                }
                ···
        }

    STEP 11
    ActivityManagerService 通过 socket 通信告知 Zygote 进程 fork 子进程,即 app 进程;

    STEP 12
    进程创建后将 ActivityThread 加载进去,执行 ActivityThread#main() 方法,实例化 ActivityThread,同时创建 ApplicationThread,Looper,Hander 对象,调用 ActivityThread#attach(false) 方法进行 Binder 通信, 接着 Looper 启动循环;


    ActivityThread.java


       public static void main(String[] args) {
           ···
            Looper.prepareMainLooper();
            ActivityThread thread = new ActivityThread();
            thread.attach(false);
            if (sMainThreadHandler == null) {
                sMainThreadHandler = thread.getHandler();
            }
            ···
            Looper.loop();
            ···
        }
        private void attach(boolean system) {
            ···
            if (!system) {
                ···
                final IActivityManager mgr = ActivityManager.getService();
                try {
                    mgr.attachApplication(mAppThread);
                } catch (RemoteException ex) {
                    throw ex.rethrowFromSystemServer();
                }
                ···
            } else {
               ···
            }
            ···
        }

    回到 system_server 中,ActivityManagerService#attachApplication(mAppThread) 方法内部调用了 thread#bindApplication() 和 mStackSupervisor#attachApplicationLocked() 这两个方法。

    STEP 13
    其中,thread#bindApplication() 方法调用了 ActivityThread#sendMessage(H.BIND_APPLICATION, data) 方法,最终走到了 ActivityThread#handleBindApplication(),进而创建 Application 对象,然后调用 Application#attach(context) 来绑定 Context ,创建完 Application 对象后便是调用 mInstrumentation#callApplicationOnCreate() 执行 Application#onCreate() 生命周期;


    ActivityManagerService.java


        @Override
        public final void attachApplication(IApplicationThread thread) {
            synchronized (this) {
                ···
                attachApplicationLocked(thread, callingPid);
                ···
            }
        }
        private final boolean attachApplicationLocked(IApplicationThread thread,
                int pid) {
            ···
            try {
                ···
                if (app.instr != null) {
                    thread.bindApplication(processName, appInfo, providers,
                            app.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);
                } else {
                    thread.bindApplication(processName, appInfo, providers, null, profilerInfo,
                            null, null, null, testMode,
                            mBinderTransactionTrackingEnabled, enableTrackAllocation,
                            isRestrictedBackupMode || !normalMode, app.persistent,
                            new Configuration(getGlobalConfiguration()), app.compat,
                            getCommonServicesLocked(app.isolated),
                            mCoreSettingsObserver.getCoreSettingsLocked(),
                            buildSerial);
                }
                ···
            } catch (Exception e) {
                ···
            }
            ···
            // See if the top visible activity is waiting to run in this process...
            if (normalMode) {
                try {
                    if (mStackSupervisor.attachApplicationLocked(app)) {
                        didSomething = true;
                    }
                } catch (Exception e) {
                    ···
                }
            }
            ···
        }


    ActivityThread#ApplicationThread.java


            public final void bindApplication(String processName, ApplicationInfo appInfo,
                ···
                sendMessage(H.BIND_APPLICATION, data);
            }


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

    我们来看看这个 mH 的 handleMessage() 方法;


    ActivityThread#H.java


            public void handleMessage(Message msg) {
                ···
                switch (msg.what) {
                    ···
                    case BIND_APPLICATION:
                        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "bindApplication");
                        AppBindData data = (AppBindData)msg.obj;
                        handleBindApplication(data);
                        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                        break;
                    ···
                }
                ···
            }

    创建 mInstrumentation 对象,调用 data#info#makeApplication 来创建 Application 对象;


    ActivityThread.java


        private void handleBindApplication(AppBindData data) {
            ···
            try {
                // 创建 Application 实例
                Application app = data.info.makeApplication(data.restrictedBackupMode, null);
                mInitialApplication = app;
                ···
                try {
                    mInstrumentation.callApplicationOnCreate(app);
                } catch (Exception e) {
                    ···
                }
            } finally {
                ···
            }
            ···
        }


    LoadedApk.java


        public Application makeApplication(boolean forceDefaultAppClass,
                Instrumentation instrumentation) {
            if (mApplication != null) {
                return mApplication;
            }
            ···
            Application app = null;
            ···
            try {
                ···
                app = mActivityThread.mInstrumentation.newApplication(
                        cl, appClass, appContext);
                ···
            } catch (Exception e) {
                ···
            }
            ···
            if (instrumentation != null) {
                try {
                    //执行 Application#onCreate() 生命周期
                    instrumentation.callApplicationOnCreate(app);
                } catch (Exception e) {
                    ···
                }
            }
            ···
            return app;
        }

    STEP 14
    mStackSupervisor#attachApplicationLocked() 方法中调用 app#thread#scheduleLaunchActivity() 即 ActivityThread#ApplicationThread#scheduleLaunchActivity() 方法,进而通过 ActivityThread#sendMessage(H.LAUNCH_ACTIVITY, r) 方法,最终走到了 ActivityThread#handleLaunchActivity() ,进而创建 Activity 对象,然后调用 activity.attach() 方法,再调用 mInstrumentation#callActivityOnCreate() 执行 Activity#onCreate() 生命周期;


    ActivityStackSupervisor.java


        boolean attachApplicationLocked(ProcessRecord app) throws RemoteException {
            for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
                ···
                for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
                    ···
                    if (hr != null) {
                        if (hr.app == null && app.uid == hr.info.applicationInfo.uid
                                && processName.equals(hr.processName)) {
                            try {
                                if (realStartActivityLocked(hr, app, true, true)) {
                                    didSomething = true;
                                }
                            } catch (RemoteException e) {
                                ···
                            }
                        }
                    }
                }
            }
            ···
        }
        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) {
                ···
            }
            ···
        }


    ActivityThread#ApplicationThread.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 pendingResults, List pendingNewIntents,
                    boolean notResumed, boolean isForward, ProfilerInfo profilerInfo) {
                ···
                sendMessage(H.LAUNCH_ACTIVITY, r);
            }


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

    我们同样来看看这个 mH 的 handleMessage() 方法;


    ActivityThread#H.java


            public void handleMessage(Message msg) {
                if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
                switch (msg.what) {
                    case LAUNCH_ACTIVITY: {
                        ···
                        handleLaunchActivity(r, null, "LAUNCH_ACTIVITY");
                        ···
                    } break;
                    ···
                }
                ···
            }


    ActivityThread.java


        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) {
                ···
        }

    到这里,整个 app 启动流程以及源码调用皆已分析完毕。
  • 回复

    使用道具 举报

    1

    主题

    473

    帖子

    -215

    积分

    限制会员

    积分
    -215
    发表于 2021-9-30 07:42:09 | 显示全部楼层
    真是 收益 匪浅
    回复

    使用道具 举报

    1

    主题

    538

    帖子

    -187

    积分

    限制会员

    积分
    -187
    发表于 2021-9-30 08:07:09 | 显示全部楼层
    相当不错,感谢无私分享精神!
    回复

    使用道具 举报

    0

    主题

    498

    帖子

    -169

    积分

    限制会员

    积分
    -169
    发表于 2021-9-30 08:27:15 | 显示全部楼层
    沙发!沙发!
    回复

    使用道具 举报

    1

    主题

    487

    帖子

    -169

    积分

    限制会员

    积分
    -169
    发表于 2021-9-30 08:47:28 | 显示全部楼层
    不错,支持下楼主
    回复

    使用道具 举报

    0

    主题

    536

    帖子

    -219

    积分

    限制会员

    积分
    -219
    发表于 2021-9-30 09:07:38 | 显示全部楼层
    不错
    回复

    使用道具 举报

    1

    主题

    482

    帖子

    -161

    积分

    限制会员

    积分
    -161
    发表于 2021-9-30 09:27:48 | 显示全部楼层
    LZ说的很不错
    回复

    使用道具 举报

    1

    主题

    468

    帖子

    -177

    积分

    限制会员

    积分
    -177
    发表于 2021-9-30 09:48:35 | 显示全部楼层
    小手一抖,积分到手!
    回复

    使用道具 举报

    1

    主题

    476

    帖子

    -149

    积分

    限制会员

    积分
    -149
    发表于 2021-9-30 10:10:03 | 显示全部楼层
    找到好贴不容易,我顶你了,谢了
    回复

    使用道具 举报

    1

    主题

    493

    帖子

    -154

    积分

    限制会员

    积分
    -154
    发表于 2021-9-30 10:30:08 | 显示全部楼层
    帮你顶下哈!!
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|无图版|手机版|小黑屋|珠海@IT精英团

    GMT+8, 2022-7-3 17:13 , Processed in 0.172966 second(s), 24 queries .

    Powered by Discuz! X3.4

    © 2020 Comsenz Inc.

    快速回复 返回顶部 返回列表