基于android-8.1.0_r60

startApplication-android-8.0.jpg

AMS提供了一个startProcessLocked函数,用于启动进程。

触发启动

就应用层而言,启动进程的方式基本上就是如下四种方式:

  • Activity
  • Service
  • Broadcast
  • Provider

# 打开Activity时

// frameworks/base/services/core/java/com/android/server/am/ActivityStackSupervisor.java
void startSpecificActivityLocked(ActivityRecord r,
        boolean andResume, boolean checkConfig) {
    ProcessRecord app = mService.getProcessRecordLocked(r.processName,
            r.info.applicationInfo.uid, true);
    if (app != null && app.thread != null) {
        try {
            realStartActivityLocked(r, app, andResume, checkConfig);
            return;
        }
    }

    // 当查询不到Activity对应进程的时候,启动进程。
    mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
            "activity", r.intent.getComponent(), false, false, true);
}

启动Activity的最后都会进到startSpecificActivityLocked函数。这里会判定目标进程是否存在,如果不存在那么调用startProcessLocked

# Service唤起进程

Service启动最终会执行到ActivServices的bringUpServiceLocked函数如下:

// frameworks/base/services/core/java/com/android/server/am/ActiveServices.java
private String bringUpServiceLocked(ServiceRecord r, int intentFlags, boolean execInFg,
        boolean whileRestarting, boolean permissionsReviewRequired)
        throws TransactionTooLargeException {
    // 如果Service所在进程存在,并且有效。那么直接调用onStartCommand??,这里的逻辑比较奇怪。
    if (r.app != null && r.app.thread != null) {
        // 最后Service的onStartCommand将会被执行
        sendServiceArgsLocked(r, execInFg, false);
        return null;
    }
    ...
    final boolean isolated = (r.serviceInfo.flags&ServiceInfo.FLAG_ISOLATED_PROCESS) != 0;
    final String procName = r.processName;
    String hostingType = "service";
    ProcessRecord app;

    if (!isolated) {
        app = mAm.getProcessRecordLocked(procName, r.appInfo.uid, false);
        if (app != null && app.thread != null) {
            try {
                app.addPackage(r.appInfo.packageName, r.appInfo.versionCode, mAm.mProcessStats);
                // 启动Service,最终Service的onCreate会被执行
                realStartServiceLocked(r, app, execInFg);
                return null;
            }
        }
    }
    if (app == null && !permissionsReviewRequired) {
        // 触发启动进程。
        if ((app=mAm.startProcessLocked(procName, r.appInfo, true, intentFlags,
                hostingType, r.name, false, isolated, false)) == null) {
            // 启动失败
            return msg;
        }
        if (isolated) {
            r.isolatedProc = app;
        }
    }
    ...
    // 将当前Service添加到待启动Service列表中。
    if (!mPendingServices.contains(r)) {
        mPendingServices.add(r);
    }
    ...
    return null;
}
  • 如果Service所在进程存在,并且有效。那么直接调sendServiceArgsLocked启动,这里最终对应的是最后Service的onStartCommand将会被执行。这里的逻辑看起来比较奇怪。
  • 重新通过进程名称在其获取一次ProcessRecord,如果存在且有效,则进入realStartServiceLocked函数。这里调用到了ApplicationThread的handleCreateService,最终Service的onCreate将被执行。
  • 最后,如果都不满足。那么就startProcessLocked,并且将当前ServiceRecord加入到mPendingServices列表。当ActivityThread回调到attachApplication时,会真正的Service跑起来。

# 广播

是的,众所周知广播也是可以将应用唤起的。

// frameworks/base/services/core/java/com/android/server/am/BroadcastQueue.java
final void processNextBroadcast(boolean fromMsg) {
    synchronized(mService) {
        BroadcastRecord r;
        mService.updateCpuStats();
        if (fromMsg) {
            mBroadcastsScheduled = false;
        }
        // 获取广播记录(BroadcastRecord)过程,略。
        ...
        // 这里是用户注册的广播,因此直接发送即可。不用考虑进程启动的事情。如果进程挂了也就拉倒吧。
        if (nextReceiver instanceof BroadcastFilter) {
            BroadcastFilter filter = (BroadcastFilter)nextReceiver;
            deliverToRegisteredReceiverLocked(r, filter, r.ordered, recIdx);
            ...
            return;
        }

        // 这是一个ResolveInfo,对应的是Manifest中注册的广播。
        ResolveInfo info = (ResolveInfo)nextReceiver;
        ComponentName component = new ComponentName(
                info.activityInfo.applicationInfo.packageName,
                info.activityInfo.name);
        ...
        r.delivery[recIdx] = BroadcastRecord.DELIVERY_DELIVERED;
        r.state = BroadcastRecord.APP_RECEIVE;
        r.curComponent = component;
        r.curReceiver = info.activityInfo;
       ...
        // 如果Manifest注册的Receiver对应的进程存活着,发送广播即可。
        if (app != null && app.thread != null && !app.killed) {
            try {
                // 通知目标进程scheduleReceiver,此时目标进程中注册了的Receiver对象将被拉起。
                processCurBroadcastLocked(r, app);
                return;
            }
            ...
        }

        // 启动进程。并且标记来自后台。
        if ((r.curApp=mService.startProcessLocked(targetProcess,
                info.activityInfo.applicationInfo, true,
                r.intent.getFlags() | Intent.FLAG_FROM_BACKGROUND,
                "broadcast", r.curComponent,
                (r.intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0, false, false))  == null) {
            // 启动失败
            return;
        }
        // 记录pendingBroadcast。这里并不是一个列表,只是一个变量
        mPendingBroadcast = r;
        mPendingBroadcastRecvIndex = recIdx;
    }
}

这里的广播是相对于Manifest而言,才会唤起进程的逻辑。

  • 用户注册的广播:注册的receiver对应的是一个BroadcastFilter对象,直接发送即可。不用考虑进程启动的事情。如果进程挂了也就拉倒吧。
  • Manifest注册进程:如果对应进程已经启动。那么通知目标进程scheduleReceiver,此时目标进程中注册了的Receiver对象将会在ActivityThread被实例化并回调onReceive函数。
  • 最后,调用startProcessLocked启动静态广播对应的进程,并将当前的BroadcastRecord记录到mPendingBroadcast中临时保存。等进程其中之后,会再次处理mPendingBroadcast。

# Provider

与上面都不同的是Provider对应进程被唤起之后,不用异步等待pending任务的回调。

原因在于,获取provider本身就是同步的调用。

下面来看看这一过程是怎么做的:

// frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
    private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
            String name, IBinder token, boolean stable, int userId) {
        ContentProviderRecord cpr;
        ContentProviderConnection conn = null;
        ProviderInfo cpi = null;
        // 通过name,即uri,拿到providerMap中对应的ContentProviderRecord

        synchronized(this) {
            long startTime = SystemClock.uptimeMillis();
            ...
            boolean checkCrossUser = true;
            // mProviderMap为应用起来之后,自动将provider实例化,并注册到AMS中。
            cpr = mProviderMap.getProviderByName(name, userId);
            if (cpr == null && userId != UserHandle.USER_SYSTEM) {
                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM);
                ...
            }
            // 运行中的provider,忽略。
            boolean providerRunning = cpr != null && cpr.proc != null && !cpr.proc.killed;
            if (!providerRunning) {
                try {
                    // 调用PMS获取ProviderInfo,此处对应的是Manifest中注册的信息。
                    cpi = AppGlobals.getPackageManager().
                        resolveContentProvider(name,
                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
                } catch (RemoteException ex) {
                }
                ...
                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
                cpr = mProviderMap.getProviderByClass(comp, userId);
                final boolean firstClass = cpr == null;
                if (firstClass) {
                    try {
                        ApplicationInfo ai =
                            AppGlobals.getPackageManager().
                                getApplicationInfo(cpi.applicationInfo.packageName, STOCK_PM_FLAGS, userId);
                        ai = getAppInfoForUser(ai, userId);
                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
                    }
                }
                ...
                // 检查provider是否正在被启动
                final int N = mLaunchingProviders.size();
                int i;
                for (i = 0; i < N; i++) {
                    if (mLaunchingProviders.get(i) == cpr) {
                        break;
                    }
                }

                // 如果没有正在被启动,那么就需要从现在开始启动。
                if (i >= N) {
                    final long origId = Binder.clearCallingIdentity();
                    try {
                        ...
                        ProcessRecord proc = getProcessRecordLocked(
                                cpi.processName, cpr.appInfo.uid, false);
                        // 如果目标进程存在,并且正常存活。
                        // 但是此时attachApplication之后还没回调到子进程。
                        // 那么就不需要再次启动进程,只需要告知子进程provider。
                        // 需要优先install,而不用等到bindApplication后publish到AMS。
                        if (proc != null && proc.thread != null && !proc.killed) {
                            if (!proc.pubProviders.containsKey(cpi.name)) {
                                proc.pubProviders.put(cpi.name, cpr);
                                try {
                                    proc.thread.scheduleInstallProvider(cpi);
                                }
                            }
                        } else {
                            // 进程无效,那么startProcessLocked(重新)启动进程
                            proc = startProcessLocked(cpi.processName,
                                    cpr.appInfo, false, 0, "content provider",
                                    new ComponentName(cpi.applicationInfo.packageName,
                                            cpi.name), false, false, false);
                            // 启动失败,直接退出。
                            if (proc == null) {
                                return null;
                            }
                        }
                        cpr.launchingApp = proc;
                        // 添加进正在启动的provider列表
                        mLaunchingProviders.add(cpr);
                    } finally {
                        Binder.restoreCallingIdentity(origId);
                    }
                }
                // 注册到缓存中去
                if (firstClass) {
                    mProviderMap.putProviderByClass(comp, cpr);
                }
                mProviderMap.putProviderByName(name, cpr);
                conn = incProviderCountLocked(r, cpr, token, stable);
                if (conn != null) {
                    conn.waiting = true;
                }
            }
        }
        synchronized (cpr) {
            while (cpr.provider == null) {
                // 一直等,直到进程启动完成,并且将当前进程的provider通过
                // publishContentProviders注册到上面提到的providerMap中去。
            }
        }
        return cpr != null ? cpr.newHolder(conn) : null;
    }

简单分析provider的过程见上面的简略代码。

直接拉到最下面,当一个provider不存的时候。最后也会调用startProcessLocked对进程的启动。

在最后会有一个while循环,一直等待ContentProviderRecord对应的provider参数(client)赋值,即子进程将Provider唤起install到AMS中。

启动进程

其实 startProcessLocked 更多的只是对启动参数的封装。生成ProcessReocrd,并缓存到列表中。

# startProcessLocked

startProcessLocked 函数如下:

// frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
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) {
    ...
    app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
    ...
    startProcessLocked(
            app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
    return (app.pid != 0) ? app : null;
}

private final void startProcessLocked(ProcessRecord app, String hostingType,
        String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
    long startTime = SystemClock.elapsedRealtime();
    ...
    try {
        ...
        int debugFlags = 0;
        // 如果applicatoinInfo包含DEBUGGABLE标志,那么会加上如下关于debug的标识位。在Zygote中会用到。
        if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
            debugFlags |= Zygote.DEBUG_ENABLE_JDWP;
            debugFlags |= Zygote.DEBUG_JAVA_DEBUGGABLE;
            debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
        }
        if ("1".equals(SystemProperties.get("debug.checkjni"))) {
            debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
        }
        String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
        if ("true".equals(genDebugInfoProperty)) {
            debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
        }
        if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
            debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
        }
        if ("1".equals(SystemProperties.get("debug.assert"))) {
            debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
        }
        if (mNativeDebuggingApp != null && mNativeDebuggingApp.equals(app.processName)) {
            // Enable all debug flags required by the native debugger.
            debugFlags |= Zygote.DEBUG_ALWAYS_JIT;          // Don't interpret anything
            debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; // Generate debug info
            debugFlags |= Zygote.DEBUG_NATIVE_DEBUGGABLE;   // Disbale optimizations
            mNativeDebuggingApp = null;
        }

        String invokeWith = null;
        if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
            // Debuggable apps may include a wrapper script with their library directory.
            String wrapperFileName = app.info.nativeLibraryDir + "/wrap.sh";
            StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
            try {
                if (new File(wrapperFileName).exists()) {
                    invokeWith = "/system/bin/logwrapper " + wrapperFileName;
                }
            } finally {
                StrictMode.setThreadPolicy(oldPolicy);
            }
        }

        String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
        if (requiredAbi == null) {
            requiredAbi = Build.SUPPORTED_ABIS[0];
        }

        String instructionSet = null;
        if (app.info.primaryCpuAbi != null) {
            instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
        }

        app.gids = gids;
        app.requiredAbi = requiredAbi;
        app.instructionSet = instructionSet;
        ...
        boolean isActivityProcess = (entryPoint == null);
        // entryPoint默认为ActivityThread
        if (entryPoint == null) entryPoint = "android.app.ActivityThread";
        ProcessStartResult startResult;
        if (hostingType.equals("webview_service")) {
            // 如果是浏览器,WebView有专门对应WebViewZygote进程来孵化。这里不讨论了。
            startResult = startWebView(entryPoint,
                    app.processName, uid, uid, gids, debugFlags, mountExternal,
                    app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
                    app.info.dataDir, null, entryPointArgs);
        } else {
            // 最终让ZygoteProcess通过socket同Zygote发送消息,
            // 最后ZygoteInit执行ActivityThread的main函数。
            // 这个过程省略,参考进程启动过程
            startResult = Process.start(entryPoint,
                    app.processName, uid, uid, gids, debugFlags, mountExternal,
                    app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
                    app.info.dataDir, invokeWith, entryPointArgs);
        }
        ...
        if (app.persistent) {
            Watchdog.getInstance().processStarted(app.processName, startResult.pid);
        }
        ...
        app.setPid(startResult.pid);
        app.usingWrapper = startResult.usingWrapper;
        app.removed = false;
        app.killed = false;
        app.killedByAm = false;
        synchronized (mPidsSelfLocked) {
            this.mPidsSelfLocked.put(startResult.pid, app);
            if (isActivityProcess) {
                // 监听启动进程是否超时,如超时则放弃。
                // 见: processStartTimedOutLocked
                Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
                msg.obj = app;
                mHandler.sendMessageDelayed(msg, startResult.usingWrapper
                    ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
                PROC_START_TIMEOUT_WITH_WRAPPER为1200秒20分钟
                而PROC_START_TIMEOUT则为10秒
            }
        }
    } catch (RuntimeException e) {
        ...
    }
}
  • 创建进程通过调用:Process.start进行启动。这里最终调用到了Zygote中间,fork出子进程。
  • ZygoteInit的entrypoint则是在这里设定的,默认为android.app.ActivityThread
  • 如果是启动Activity则存在启动进程超时:默认PROC_START_TIMEOUT则为10秒。

# Zygote子进程

这里将ZygoteProcess到ZygoteInit->Zygote->RuntimeInit最后到ActivityThread的过程省略。

直接看ActivityThread的main函数:

// frameworks/base/core/java/android/app/ActivityThread.java
final ApplicationThread mAppThread = new ApplicationThread();
public static void main(String[] args) {
    ...
    Looper.prepareMainLooper();
    ActivityThread thread = new ActivityThread();
    // 实例化ApplicationThread并将其Attach到AMS
    thread.attach(false);
    if (sMainThreadHandler == null) {
        sMainThreadHandler = thread.getHandler();
    }
    if (false) {
        // trigger:这里可以监控MessageQueue每次处理消息的耗时。
        Looper.myLooper().setMessageLogging(new
                LogPrinter(Log.DEBUG, "ActivityThread"));
    }
    Looper.loop();
}

ActivityThread的main函数,实例化ActivityThread对象,并attach到AMS。

最后将创建的MainLooper进行loop,接收输入事件/VSYNC等将应用跑起来。

下面来看看attach做了什么:

// frameworks/base/core/java/android/app/ActivityThread.java
private void attach(boolean system) {
    sCurrentActivityThread = this;
    mSystemThread = system;
    if (!system) {
        // 普通进程
        ViewRootImpl.addFirstDrawHandler(new Runnable() {
            @Override
            public void run() {
                // 第一次draw时会发送一个post消息回调到这里
                ensureJitEnabled();
            }
        });
        RuntimeInit.setApplicationObject(mAppThread.asBinder());
        final IActivityManager mgr = ActivityManager.getService();
        try {
            // 通知AMS进程已经启动
            mgr.attachApplication(mAppThread);
        } catch (RemoteException ex) {
            throw ex.rethrowFromSystemServer();
        }
        // 监控GC,并适当情况下,释放当前的一些Activity实例。以满足内存要求
        BinderInternal.addGcWatcher(new Runnable() {
            @Override public void run() {
                if (!mSomeActivitiesChanged) {
                    return;
                }
                Runtime runtime = Runtime.getRuntime();
                long dalvikMax = runtime.maxMemory();
                long dalvikUsed = runtime.totalMemory() - runtime.freeMemory();
                if (dalvikUsed > ((3*dalvikMax)/4)) {
                    if (DEBUG_MEMORY_TRIM) Slog.d(TAG, "Dalvik max=" + (dalvikMax/1024)
                            + " total=" + (runtime.totalMemory()/1024)
                            + " used=" + (dalvikUsed/1024));
                    mSomeActivitiesChanged = false;
                    try {
                        mgr.releaseSomeActivities(mAppThread);
                    } catch (RemoteException e) {
                        throw e.rethrowFromSystemServer();
                    }
                }
            }
        });
    } else {
    // SystemServer进程
        android.ddm.DdmHandleAppName.setAppName("system_process",
                UserHandle.myUserId());
        try {
            mInstrumentation = new Instrumentation();
            ContextImpl context = ContextImpl.createAppContext(
                    this, getSystemContext().mPackageInfo);
            mInitialApplication = context.mPackageInfo.makeApplication(true, null);
            mInitialApplication.onCreate();
        } catch (Exception e) {
        }
    }
    ...
}

子进程调用mgr.attachApplication(mAppThread);,将自己的ApplicationThread注册到AMS。之后AMS可以通过这个binder实现对ActivityThread的调用。

回调到AMS

// frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
@Override
public final void attachApplication(IApplicationThread thread) {
    synchronized (this) {
        int callingPid = Binder.getCallingPid();
        final long origId = Binder.clearCallingIdentity();
        attachApplicationLocked(thread, callingPid);
        Binder.restoreCallingIdentity(origId);
    }
}
// frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
private final boolean attachApplicationLocked(IApplicationThread thread,
        int pid) {
    ProcessRecord app;
    long startTime = SystemClock.uptimeMillis();
    if (pid != MY_PID && pid >= 0) {
        synchronized (mPidsSelfLocked) {
            app = mPidsSelfLocked.get(pid);
        }
    }
    这里如果找不到ProcessRecord很有可能是启动进程超时被被销毁了
    if (app == null) {
        if (pid > 0 && pid != MY_PID) {
            killProcessQuiet(pid);
        } else {
            thread.scheduleExit();
        }
        return false;
    }
    ...
    final String processName = app.processName;
    try {
        // 监控ApplicatoinThread的binder死亡消息
        // 即监控应用进程的死亡。
        AppDeathRecipient adr = new AppDeathRecipient(
                app, pid, thread);
        thread.asBinder().linkToDeath(adr, 0);
        app.deathRecipient = adr;
    }
    ...
    app.makeActive(thread, mProcessStats);
    ...
    boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
    ...
    try {
        ...
        ApplicationInfo appInfo = app.instr != null ? app.instr.mTargetInfo : app.info;
        app.compat = compatibilityInfoForPackageLocked(appInfo);
        ...
        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 {
            // 通知进程启动Application
            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);
        }
        LRU策略更新ProcessRecord在mLruProcesses的位置
        updateLruProcessLocked(app, false, null);
        app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
    } catch (Exception e) {
        return false;
    }

    mProcessesOnHold.remove(app);
    boolean badApp = false;
    boolean didSomething = false;

    // 查看是否有需要启动的Activity
    if (normalMode) {
            if (mStackSupervisor.attachApplicationLocked(app)) {
                didSomething = true;
            }
    }

    // 查看是否有需要启动的Service
    if (!badApp) {
            didSomething |= mServices.attachApplicationLocked(app, processName);
    }

    // 查看是否有广播需要处理
    if (!badApp && isPendingBroadcastProcessLocked(pid)) {
            didSomething |= sendPendingBroadcastsLocked(app);
    }

    // 查看是否有需要启动的备份消息
    if (!badApp && mBackupTarget != null && mBackupTarget.app == app) {
        try {
            thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
                    compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
                    mBackupTarget.backupMode);
        }
    }
    ...
    return true;
}
  • 启动超时

如果启动进程超时,那么ProcessRecord会被清除。此时这个进程将会被劝退。

具体逻辑看startProcessRecord时发送的PROC_START_TIMEOUT_MSG消息。

  • 监听死亡

通过Binder的death消息,监控子进程的生命周期。

// frameworks/base/services/core/java/com/android/server/am/ActivityManagerService$AppDeathRecipient.java
private final class AppDeathRecipient implements IBinder.DeathRecipient {
    final ProcessRecord mApp;
    final int mPid;
    final IApplicationThread mAppThread;
    ...
    @Override
    public void binderDied() {
        synchronized(ActivityManagerService.this) {
            appDiedLocked(mApp, mPid, mAppThread, true);
        }
    }
}

具体见appDiedLocked函数。

  • bindApplication:

调用applicationThread的bindApplication,通知子进程启动Application。

这一步主要是三件事:

创建baseContext

实例化Applicatoin

实例化所有provider并publish回AMS

By @hyongbai 共23962个字

本文链接 http://yourbay.me/all-about-tech/2019/08/23/android-8.0-startApplication/