startService启动应用进程流程

本文深入解析了Android系统中服务启动的具体流程,特别是当目标服务所在进程尚未创建时系统的处理方式。通过跟踪ContextImpl.java中的startService方法调用,揭示了ActivityManagerService如何协调服务的启动与进程的创建。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

ContextImpl.java中startService启动一个服务,本文是为了弄清楚当该服务所要运行的进程尚未创建时,系统是如何启动的。

    public ComponentName startService(Intent service) {
        ......
        return startServiceCommon(service, mUser);
    }

    private ComponentName startServiceCommon(Intent service, UserHandle user) {
        try {
            ......
            ComponentName cn = ActivityManagerNative.getDefault().startService(
                mMainThread.getApplicationThread(), service, service.resolveTypeIfNeeded(
                            getContentResolver()), getOpPackageName(), user.getIdentifier());
            ......
            return cn;
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

ActivityManagerNative是个抽象类,由ActivityManagerService即AMS继承,因此转到AMS

@Override
public ComponentName startService(IApplicationThread caller, Intent service, String resolvedType, String callingPackage, int userId) throws TransactionTooLargeException {
        synchronized(this) {
            ......
            ComponentName res = mServices.startServiceLocked(caller, service, resolvedType, callingPid, callingUid, callingPackage, userId);
            Binder.restoreCallingIdentity(origId);
            return res;
        }
    }

ComponentName startServiceLocked(IApplicationThread caller, Intent service, String resolvedType,int callingPid, int callingUid, String callingPackage, final int userId) throws TransactionTooLargeException {
        //从PM或缓存中检索服务
        ServiceLookupResult res =
            retrieveServiceLocked(service, resolvedType, callingPackage, callingPid, callingUid, userId, true, callerFg, false);
        ......
        ServiceRecord r = res.record;
        ......
        r.lastActivity = SystemClock.uptimeMillis();
        r.startRequested = true;
        r.delayedStop = false;
        //将要启动的请求添加到服务的pendingStarts中
        r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(), service, neededGrants));
        ......

        mBringUpReason = BRING_UP_START_SERVICE;
        mCurrentCallerPackage = callingPackage;
        mCurrentCallerUid = callingUid;

        return startServiceInnerLocked(smap, service, r, callerFg, addToStarting);
    }

ComponentName startServiceInnerLocked(ServiceMap smap, Intent service, ServiceRecord r, boolean callerFg, boolean addToStarting) throws TransactionTooLargeException {
        ......
        String error = bringUpServiceLocked(r, service.getFlags(), callerFg, false, false);
        ......

        if (r.startRequested && addToStarting) {
        //如果需要延迟服务的启动,默认延迟15s
            boolean first = smap.mStartingBackground.size() == 0;
            smap.mStartingBackground.add(r);
            r.startingBgTimeout = SystemClock.uptimeMillis() + BG_START_TIMEOUT;
......
            if (first) {
                smap.rescheduleDelayedStarts();
            }
        } else if (callerFg) {
            smap.ensureNotStartingBackground(r);
        }

        return r.name;
    }

private String bringUpServiceLocked(ServiceRecord r, int intentFlags, boolean execInFg, boolean whileRestarting, boolean permissionsReviewRequired) throws TransactionTooLargeException {
        //如果这个服务记录中进程和线程都不为空,说明已经启动了
        if (r.app != null && r.app.thread != null) {
            sendServiceArgsLocked(r, execInFg, false);
            return null;
        }
        //如果正在重启或需要延迟重启,返回
        if (!whileRestarting && r.restartDelay > 0) {
            // If waiting for a restart, then do nothing.
            return null;
        }

        //设置包的状态
        try {
             AppGlobals.getPackageManager().setPackageStoppedState(
 r.packageName, false, r.userId);
        } catch (RemoteException e) {
        } catch (IllegalArgumentException e) {
            Slog.w(TAG, "Failed trying to unstop package "
                    + r.packageName + ": " + e);
        }

        final boolean isolated = (r.serviceInfo.flags&ServiceInfo.FLAG_ISOLATED_PROCESS) != 0;
        final String procName = r.processName;
        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);
                    realStartServiceLocked(r, app, execInFg);
                    return null;
                } catch (TransactionTooLargeException e) {
                    throw e;
                } catch (RemoteException e) {
                    Slog.w(TAG, "Exception when starting service " + r.shortName, e);
                }
            }
        } else {
            app = r.isolatedProc;
        }

        //如果进程还没起来
        if (app == null && !permissionsReviewRequired) {
            ......
            //启动进程
            if ((app=mAm.startProcessLocked(procName, r.appInfo, true, intentFlags, "service", r.name, false, isolated, false)) == null) {
                    bringDownServiceLocked(r);
                    return msg;
                }
                if (isolated) {
                    r.isolatedProc = app;
                }
        } else {
            ......
        }
        ......
        return null;
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值