【Framework】startService启动流程

前言

启动service有两种方式:startService和bindService。 这一篇先讲startService,读者如果只想看流程图,可以直接跳到总结。

1. ContextImpl

代码路径:frameworks\base\core\java\android\app\ContextImpl.java

1.1 startService

我们在调用startService的时候,实际是调用到ContextImpl的startService

@Override
public ComponentName startService(Intent service) {
   
   
    warnIfCallingFromSystemProcess();
    return startServiceCommon(service, false, mUser);
}

1.2 startServiceCommon

startServiceCommon通过ActivityManager获取AMS的接口IActivityManager,将启动service请求发送给AMS

private ComponentName startServiceCommon(Intent service, boolean requireForeground,
                                         UserHandle user) {
   
   
    try {
   
   
        // 调用AMS的IActivityManager接口启动service
        ComponentName cn = ActivityManager.getService().startService(
                mMainThread.getApplicationThread(), service,
                service.resolveTypeIfNeeded(getContentResolver()), requireForeground,
                getOpPackageName(), getAttributionTag(), user.getIdentifier());
        if (cn != null) {
   
   
            if (cn.getPackageName().equals("!")) {
   
   
                throw new SecurityException("Not allowed to start service " + service
                        + " without permission " + cn.getClassName());
            } else if (cn.getPackageName().equals("!!")) {
   
   
                throw new SecurityException("Unable to start service " + service
                        + ": " + cn.getClassName());
            } else if (cn.getPackageName().equals("?")) {
   
   
                throw ServiceStartNotAllowedException.newInstance(requireForeground,
                        "Not allowed to start service " + service + ": " + cn.getClassName());
            }
        }
        return cn;
    } catch (RemoteException e) {
   
   
        throw e.rethrowFromSystemServer();
    }
}

2. ActivityManagerService

代码路径:frameworks\base\services\core\java\com\android\server\am\ActivityManagerService.java

2.1 startService

AMS 的startService 实现如下

final ActiveServices mServices;
@Override
public ComponentName startService(IApplicationThread caller, Intent service ...) throws TransactionTooLargeException {
   
   
    synchronized(this) {
   
   
        // 通过Binder获取调用方的进程id
        final int callingPid = Binder.getCallingPid();
        // 通过Binder获取调用方的uid
        final int callingUid = Binder.getCallingUid();
        final long origId = Binder.clearCallingIdentity();
        ComponentName res;
        try {
   
   
            res = mServices.startServiceLocked(caller, service,
                    resolvedType, callingPid, callingUid,
                    requireForeground, callingPackage, callingFeatureId, userId);
        } finally {
   
   
            Binder.restoreCallingIdentity(origId);
        }
        return res;
    }
}

3. ActiveServices

代码路径:frameworks\base\services\core\java\com\android\server\am\ActiveServices.java

3.1 startServiceLocked

ComponentName startServiceLocked(IApplicationThread caller, Intent service ...) throws TransactionTooLargeException {
   
   
    return startServiceLocked(caller, service ....);
}

3.2 startServiceLocked

ComponentName startServiceLocked(IApplicationThread caller, Intent service ...) throws TransactionTooLargeException {
   
   
    ....
    // 如果客户端尝试启动/连接的是别名,那么我们需要返回
    // 客户端的别名组件名称,而不是“目标”组件名称,
    final ComponentName realResult = startServiceInnerLocked(r, service, callingUid, callingPid, fgRequired, callerFg, allowBackgroundActivityStarts, backgroundActivityStartsToken);
    if (res.aliasComponent != null
            && !realResult.getPackageName().startsWith("!")
            && !realResult.getPackageName().startsWith("?")) {
   
   
        return res.aliasComponent;
    } else {
   
   
        return realResult;
    }
}

3.3 startServiceInnerLocked

内部有两个startServiceInnerLocked 的重载,这里只分析最后一个:

ComponentName startServiceInnerLocked(ServiceMap smap, Intent service, ServiceRecord r ...) throws TransactionTooLargeException {
   
   
    final int uid = r.appInfo.uid;
    final String packageName = r.name.getPackageName();
    final String serviceName = r.name.getClassName();
    mAm.mBatteryStatsService.noteServiceStartRunning(uid, packageName, serviceName);
    // 准备启动service
    String error = bringUpServiceLocked(r, service.getFlags(), callerFg,
            false /* whileRestarting */,
            false /* permissionsReviewRequired */
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值