android源码分析目录

一 概述

Service 的发动,应该是四大组件里最简略的,所以咱们就从 Service 的发动开端,看来 ActivityManagerService 和四大组件的发动流程。

注:本文源码基于 Android12(android-12.0.0_r1)

二 Context

仍是从 Context 出发,当咱们调用 startService 的时分,会通过 Context -> ContextWrapper -> ComtextImpl 这个流程,最终调用到 AcitivityManagerService 里。

2.1 startService

[frameworks/base/core/java/android/app/ContextImpl.java]
@Override
public ComponentName startService(Intent service) {
    warnIfCallingFromSystemProcess();
    return startServiceCommon(service, false, mUser);
}

2.2 startServiceCommon


private ComponentName startServiceCommon(Intent service, boolean requireForeground,
        UserHandle user) {
    try {
        validateServiceIntent(service);
        service.prepareToLeaveProcess(this);
		// 通过 AMS 的Binder 目标,调用 startService
        ComponentName cn = ActivityManager.getService().startService(
                mMainThread.getApplicationThread(), service,
                service.resolveTypeIfNeeded(getContentResolver()), requireForeground,
                getOpPackageName(), getAttributionTag(), user.getIdentifier());
        ...
}

三 ActivityManagerService

从这一步开端,调用就从使用进程转到了体系进程了。首先是 AMS 中,有一个 mServices 变量,它是一个 ActiveServices 目标。

3.1 startService


[frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java]
@Override
public ComponentName startService(IApplicationThread caller, Intent service,
        String resolvedType, boolean requireForeground, String callingPackage,
        String callingFeatureId, int userId)
        throws TransactionTooLargeException {
	   ...
        try {
	        // mServices 是一个 ActiveServices 目标。
            res = mServices.startServiceLocked(caller, service,
                    resolvedType, callingPid, callingUid,
                    requireForeground, callingPackage, callingFeatureId, userId);
        } finally {
            Binder.restoreCallingIdentity(origId);
        }
        return res;
    }
}

调用 ActiveServices 的 startServiceLocked。

四 ActiveServices

ActiveServices 中 startServiceLocked 的流程很长,所以我将其中不重要的代码省掉了,只留下了骨干代码。

4.1 startServiceLocked

[frameworks/base/services/core/java/com/android/server/am/ActiveServices.java]
ComponentName startServiceLocked(IApplicationThread caller, Intent service, String resolvedType,
    int callingPid, int callingUid, boolean fgRequired,
    String callingPackage, @Nullable String callingFeatureId, final int userId,
    boolean allowBackgroundActivityStarts, @Nullable IBinder backgroundActivityStartsToken)
    throws TransactionTooLargeException {
// 是否是前台服务
final boolean callerFg;
if (caller != null) {
    final ProcessRecord callerApp = mAm.getRecordForAppLOSP(caller);
    if (callerApp == null) {
       ...	// 反常处理
    }
    callerFg = callerApp.mState.getSetSchedGroup() != ProcessList.SCHED_GROUP_BACKGROUND;
} else {
    callerFg = true;
}
// 检索服务信息 [见4.2]
ServiceLookupResult res =
    retrieveServiceLocked(service, null, resolvedType, callingPackage,
            callingPid, callingUid, userId, true, callerFg, false, false);
// 一定要检索到对应的服务才能履行后边的流程
if (res == null) {
    return null;
}
if (res.record == null) {
    return new ComponentName("!", res.permission != null
            ? res.permission : "private to package");
}
// res.record 其实便是 ServiceRecord,便是咱们要发动的服务
ServiceRecord r = res.record;
setFgsRestrictionLocked(callingPackage, callingPid, callingUid, service, r, userId,
        allowBackgroundActivityStarts);
if (!mAm.mUserController.exists(r.userId)) {
    Slog.w(TAG, "Trying to start service with non-existent user! " + r.userId);
    return null;
}
// 是否后台发动服务
final boolean bgLaunch = !mAm.isUidActiveLOSP(r.appInfo.uid);
//
boolean forcedStandby = false;
if (bgLaunch && appRestrictedAnyInBackground(r.appInfo.uid, r.packageName)) {
    forcedStandby = true;
}
... // 省掉代码
// 静默制止标志,假如权限判别不通过,切有此标志,那么会中止发动服务切不通知用户
boolean forceSilentAbort = false;
// 权限判别,是否能够直接前台发动服务
if (fgRequired) {
       ... // 省掉代码
}
//不是直接前台发动服务的权限判别,例如使用是否能够后台发动服务
if (forcedStandby || (!r.startRequested && !fgRequired)) {
   ... // 省掉代码
}
... // 省掉代码,后边都是权限判别的相关逻辑
// 发动服务的代码
return startServiceInnerLocked(r, service, callingUid, callingPid, fgRequired, callerFg,
        allowBackgroundActivityStarts, backgroundActivityStartsToken);
}

在 ActiveServices 的 startServiceLocked 中,首先会检索对应的 Service,它用 ServiceRecord 封装,然后保存到了 ServiceLookupResult 中。

4.2 retrieveServiceLocked

retrieveServiceLocked 便是查找 Service 信息,这个信息会封装在一个 ServiceRecord 中,后续再来查找就能够复用这个信息。

private ServiceLookupResult retrieveServiceLocked(Intent service,
        String instanceName, String resolvedType, String callingPackage,
        int callingPid, int callingUid, int userId,
        boolean createIfNeeded, boolean callingFromFg, boolean isBindExternal,
        boolean allowInstant) {
    ServiceRecord r = null;
    // 获取 userId
    userId = mAm.mUserController.handleIncomingUser(callingPid, callingUid, userId,
            /* allowAll= */false, getAllowMode(service, callingPackage),
            /* name= */ "service", callingPackage);
    // 在 ActiveServices 中有一个 SparseArray
    // 这儿是通过 userId 查询 SparseArray 中对应的 ServiceMa
    ServiceMap smap = getServiceMapLocked(userId);
    // 获取 Service 全类名
    // 全类名 = 包名 + 类名 + instanceName,这儿 instanceName 是 null
    final ComponentName comp;
    if (instanceName == null) {
        comp = service.getComponent();
    } else {
        final ComponentName realComp = service.getComponent();
        comp = new ComponentName(realComp.getPackageName(),
                realComp.getClassName() + ":" + instanceName);
    }
    // 在 ServiceMap 中查询 Service 信息,保存在 ServiceRecord 中
    if (comp != null) {
        r = smap.mServicesByInstanceName.get(comp);
    }
    //通过 filter 来查询 Service
    if (r == null && !isBindExternal && instanceName == null) {
        Intent.FilterComparison filter = new Intent.FilterComparison(service);
        r = smap.mServicesByIntent.get(filter);
    }
    ... // 代码省掉
    // 假如没有拿到 ServiceRecord
    if (r == null) {
        try {
            ... // 代码省掉
            if (userId > 0) {
                if (mAm.isSingleton(sInfo.processName, sInfo.applicationInfo,
                        sInfo.name, sInfo.flags)
                        && mAm.isValidSingletonCall(callingUid, sInfo.applicationInfo.uid)) {
                    userId = 0;
                    smap = getServiceMapLocked(0);
                    // Bypass INTERACT_ACROSS_USERS permission check
                    final long token = Binder.clearCallingIdentity();
                    try {
                    	// 没有能够复用的 ServiceRecord,则需求去 Apk 中查找,查找功能 PMS 完结
                    	// 这儿是通过 AMS 拿到 PMS
                        ResolveInfo rInfoForUserId0 =
                                mAm.getPackageManagerInternal().resolveService(service,
                                        resolvedType, flags, userId, callingUid);
                        if (rInfoForUserId0 == null) {
                            return null;
                        }
                        sInfo = rInfoForUserId0.serviceInfo;
                    } finally {
                        Binder.restoreCallingIdentity(token);
                    }
                }
                sInfo = new ServiceInfo(sInfo);
                sInfo.applicationInfo = mAm.getAppInfoForUser(sInfo.applicationInfo, userId);
            }
            ... // 代码省掉
        } catch (RemoteException ex) {
            // pm is in same process, this will never happen.
        }
    }
    ... // 代码省掉
    return null;
}

查找 Service 信息首先会依据用户的 userId 查找,看看 ActiveService 里有没有现成的,有就直接获取。 假如没有,就需求通过 PMS 解析,然后再将它封装到 ServiceRecord 中。

4.3 startServiceInnerLocked

在 ActiveServices 中,存在两个 startServiceInnerLocked 函数,它们的参数不同,第一个 startServiceInnerLocked 会在结束调用第二个,所以咱们先看第一个函数。

第一个 startServiceInnerLocked

private ComponentName startServiceInnerLocked(ServiceRecord r, Intent service,
		int callingUid, int callingPid, boolean fgRequired, boolean callerFg,
		boolean allowBackgroundActivityStarts, @Nullable IBinder backgroundActivityStartsToken)
		throws TransactionTooLargeException {
	... // 省掉代码
	r.lastActivity = SystemClock.uptimeMillis();
	r.startRequested = true;
	r.delayedStop = false;
	r.fgRequired = fgRequired;
	r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
			service, neededGrants, callingUid));
	... // 省掉代码
	ComponentName cmp = startServiceInnerLocked(smap, service, r, callerFg, addToStarting);
	return cmp;
}

在第一个 startServiceInnerLocked 中,咱们需求留意到,体系将咱们需求发动的 Service 添加到了一个 pendingStarts 的调集。这个调集后续便是回调咱们 Service 生命周期用的。

第二个 startServiceInnerLocked

ComponentName startServiceInnerLocked(ServiceMap smap, Intent service, ServiceRecord r,
        boolean callerFg, boolean addToStarting) throws TransactionTooLargeException {
    synchronized (mAm.mProcessStats.mLock) {
        final ServiceState stracker = r.getTracker();
        if (stracker != null) {
            stracker.setStarted(true, mAm.mProcessStats.getMemFactorLocked(), r.lastActivity);
        }
    }
    r.callStart = false;
    final int uid = r.appInfo.uid;
    final String packageName = r.name.getPackageName();
    final String serviceName = r.name.getClassName();
    FrameworkStatsLog.write(FrameworkStatsLog.SERVICE_STATE_CHANGED, uid, packageName,
            serviceName, FrameworkStatsLog.SERVICE_STATE_CHANGED__STATE__START);
    mAm.mBatteryStatsService.noteServiceStartRunning(uid, packageName, serviceName);
    // 发动 Service
    String error = bringUpServiceLocked(r, service.getFlags(), callerFg,
            false /* whileRestarting */,
            false /* permissionsReviewRequired */,
            false /* packageFrozen */,
            true /* enqueueOomAdj */);
    /* Will be a no-op if nothing pending */
    ... // 代码省掉
    return r.name;
}

4.4 bringUpServiceLocked

bringUpServiceLocked 这个函数很长,其实逻辑很简略

  1. 假如服务地点的进程存在,就直接回调服务的函数。
  2. 假如服务地点的进程不存在,就先发动服务进程。

private String bringUpServiceLocked(ServiceRecord r, int intentFlags, boolean execInFg,
        boolean whileRestarting, boolean permissionsReviewRequired, boolean packageFrozen,
        boolean enqueueOomAdj)
        throws TransactionTooLargeException {
	// 假如服务地点是进程 ActivityThread 存在,就调用 sendServiceArgsLocked
	// 最终调用到 ActivityThread 中的 scheduleServiceArgs
	// 然后是 handleServiceArgs -> service.onStartCommand
    if (r.app != null && r.app.getThread() != null) {
        sendServiceArgsLocked(r, execInFg, false);
        return null;
    }
    if (!whileRestarting && mRestartingServices.contains(r)) {
        // 假如服务在重启,就什么也不做
        return null;
    }
    if (mRestartingServices.remove(r)) {
        clearRestartingIfNeededLocked(r);
    }
    // 假如服务有延迟发动的标志也去掉,由于现在现已开端发动服务了
    if (r.delayed) {
        getServiceMapLocked(r.userId).mDelayedStartList.remove(r);
        r.delayed = false;
    }
    // 确保服务地点的user现已发动,否则中止。
    if (!mAm.mUserController.hasStartedUserState(r.userId)) {
        // 中止发动服务
        bringDownServiceLocked(r, enqueueOomAdj);
        return msg;
    }
    ... // 省掉代码
    if (!isolated) {
		// 先依据进程名和uid,查询进程是否存在
        app = mAm.getProcessRecordLocked(procName, r.appInfo.uid);
        if (app != null) {
	        // 进程存在,就直接发动服务
            final IApplicationThread thread = app.getThread();
            final int pid = app.getPid();
            final UidRecord uidRecord = app.getUidRecord();
            if (thread != null) {
                try {
                    app.addPackage(r.appInfo.packageName, r.appInfo.longVersionCode,
                            mAm.mProcessStats);
					// 真实发动服务的函数
                    realStartServiceLocked(r, app, thread, pid, uidRecord, execInFg,
                            enqueueOomAdj);
                     // 留意,假如是发动服务,就从这儿返回了
                    return null;
                } catch (TransactionTooLargeException e) {
                    throw e;
                } catch (RemoteException e) {
                    Slog.w(TAG, "Exception when starting service " + r.shortInstanceName, e);
                }
            }
        }
    } else {
            ... // 代码省掉
    }
    // 进程不存在,就要先发动进程
    if (app == null && !permissionsReviewRequired && !packageFrozen) {
	    // mAm 是 ActivityManagerService
	    // 这儿便是发动进程的逻辑
        if ((app = mAm.startProcessLocked(procName, r.appInfo, true, intentFlags,
                    hostingRecord, ZYGOTE_POLICY_FLAG_EMPTY, false, isolated)) == null) {
            // 进程发动失利,中止发动服务
            bringDownServiceLocked(r, enqueueOomAdj);
            return msg;
        }
        if (isolated) {
            r.isolatedProc = app;
        }
    }
    ... // 省掉代码
	// 前面进程存在,发动服务的现已返回了,进程不存在的还在发动进程,
	// 所以咱们只能先即将发动的服务添加到 mPendingServices 中,等进程发动完结之后
	// 再来发动咱们的服务
	if (!mPendingServices.contains(r)) {
		mPendingServices.add(r);
	}
     ... // 代码省掉
    return null;
}

4.5 realStartServiceLocked

private void realStartServiceLocked(ServiceRecord r, ProcessRecord app,
        IApplicationThread thread, int pid, UidRecord uidRecord, boolean execInFg,
        boolean enqueueOomAdj) throws RemoteException {
    ... // 代码省掉
	// 判别超时
    bumpServiceExecutingLocked(r, execInFg, "create", null /* oomAdjReason */);
     ... // 代码省掉
    try {
          ... // 代码省掉
         // scheduleCreateService
         // 调用 Service 的 onCreate
        thread.scheduleCreateService(r, r.serviceInfo,
                mAm.compatibilityInfoForPackage(r.serviceInfo.applicationInfo),
                app.mState.getReportedProcState());
        r.postNotification();
        created = true;
    } catch (DeadObjectException e) {
        Slog.w(TAG, "Application dead when creating service " + r);
        mAm.appDiedLocked(app, "Died when creating service");
        throw e;
    } finally {
        if (!created) {
            // Keep the executeNesting count accurate.
            final boolean inDestroying = mDestroyingServices.contains(r);
            serviceDoneExecutingLocked(r, inDestroying, inDestroying, false);
            // Cleanup.
            if (newService) {
                psr.stopService(r);
                r.setProcess(null, null, 0, null);
            }
            // Retry.
            if (!inDestroying) {
	            // 服务发动失利,重试一次
                scheduleServiceRestartLocked(r, false);
            }
        }
    }
    if (r.allowlistManager) {
        psr.mAllowlistManager = true;
    }
	// 恳求 Service 绑定 [见9.3]
    requestServiceBindingsLocked(r, execInFg);
      ... // 代码省掉
	// 调用 Service 的 onStartCommand
    sendServiceArgsLocked(r, execInFg, true);
    if (r.delayedStop) {
        r.delayedStop = false;
        if (r.startRequested) {
            // 中止服务
            stopServiceLocked(r, enqueueOomAdj);
        }
    }
}

realStartServiceLocked 名字便是看得出来,它的真实发动服务的函数,所以这儿会做发动服务的操作,后续还会回调 Service 对应的生命周期。

  • scheduleCreateService -> 调用 Service 的 onCreate
  • sendServiceArgsLocked -> 通过 r.app.getThread().scheduleServiceArgs -> ActivityThread.handleServiceArgs 调用到 Service 的 onStartCommand

然后关于 Service 发动时,出现的 ANR 也是这儿进行的。

然后这儿还有一个 scheduleServiceRestartLocked,它是用于服务重启的,服务发动失利是会主动重启的,这个函数会即将重启的服务,添加到一个 pendingStarts 调集,然后调用到 startServiceInnerLocked 中进行发动服务的操作。

关于服务重启的流程,这儿就不扩展了,服务重启的相关参数也会保存到 ServiceRecord 中,而且假如重启失利,重启的次数也会记录在 ServiceRecord 中,重启失利的次数越多,下次重启所延迟的时刻也就越久。

4.6 bumpServiceExecutingLocked

    private boolean bumpServiceExecutingLocked(ServiceRecord r, boolean fg, String why,
            @Nullable String oomAdjReason) {
        ... // 省掉代码
        if (r.executeNesting == 0) {
            r.executeFg = fg;
            ...
            if (r.app != null) {
                psr = r.app.mServices;
                psr.startExecutingService(r);
                psr.setExecServicesFg(psr.shouldExecServicesFg() || fg);
                if (timeoutNeeded && psr.numberOfExecutingServices() == 1) {
	       // 发送判别超时的音讯
                    scheduleServiceTimeoutLocked(r.app);
                }
            }
        } else if (r.app != null && fg) {
            psr = r.app.mServices;
            if (!psr.shouldExecServicesFg()) {
                psr.setExecServicesFg(true);
                if (timeoutNeeded) {
	       // 发送判别超时的音讯
                    scheduleServiceTimeoutLocked(r.app);
                }
            }
        }
        ... // 省掉代码
        return oomAdjusted;
    }

4.7 scheduleServiceTimeoutLocked


// 前台超时时刻是 20 秒
static final int SERVICE_TIMEOUT = 20 * 1000 * Build.HW_TIMEOUT_MULTIPLIER;
// 后台超时时刻是前台的 10 倍
static final int SERVICE_BACKGROUND_TIMEOUT = SERVICE_TIMEOUT * 10;
void scheduleServiceTimeoutLocked(ProcessRecord proc) {
	...
	Message msg = mAm.mHandler.obtainMessage(
			ActivityManagerService.SERVICE_TIMEOUT_MSG);
	msg.obj = proc;
	// 发送一个延迟音讯,到时分服务服务还没有发动,就会报 ANR
	// mAm 是 ActivityManagerService
	mAm.mHandler.sendMessageDelayed(msg, proc.mServices.shouldExecServicesFg()
			? SERVICE_TIMEOUT : SERVICE_BACKGROUND_TIMEOUT);
}

在 scheduleServiceTimeoutLocked 函数中发送了一个延迟音讯,前台和后台的服务时刻是不一样的,假如到了时刻这个音讯还没有被移除,那么就会在 ActivityManagerService 中处理这条音讯。这儿的调用很简略,最终会调用到 ActiveServices 的 serviceTimeout 中。

void serviceTimeout(ProcessRecord proc) {
	... // 省掉代码
	if (anrMessage != null) {
		// 最终调用 AMS 中的 mAnrHelper.appNotResponding
		mAm.mAnrHelper.appNotResponding(proc, anrMessage);
	}
}

4.8 sendServiceArgsLocked

private final void sendServiceArgsLocked(ServiceRecord r, boolean execInFg,
		boolean oomAdjusted) throws TransactionTooLargeException {
	final int N = r.pendingStarts.size();
	if (N == 0) {
		return;
	}
	ArrayList<ServiceStartArgs> args = new ArrayList<>();
	... // 省掉代码
	try {
		r.app.getThread().scheduleServiceArgs(r, slice);
	} catch (TransactionTooLargeException e) {
	... // 省掉代码
}

最终再来看一下 onStartCommand 生命周期是怎么回调的,在 sendServiceArgsLocked 函数中首先会判别 pendingStarts 这个调集是否为空。

之前的 realStartServiceLocked 中现已将咱们要发动的 Service 添加进去了,然后在这儿通过 r.app.getThread().scheduleServiceArgs 调用到 ActivityThread 中,最终通过 Handler 机制切换线程,调用到 Service 的 onStartCommand 中。

到此,Service 的 startService 发动流程咱们就梳理完一半了。

五 进程发动后

前面的 [4.4] 中咱们具体说了假如进程存在,咱们能够直接发动服务,那么假如进程不存在呢?咱们还要先发动进程。

发动进程的流程很长,它需求 Zygote 先 fork 出咱们需求的进程,然后履行 Application 的发动,这儿咱们就不具体说明这个流程了,后续会独自说明。当进程发动完结之后,会回调到 AMS 中的 attachApplicationLocked 这个函数,而在这个函数中,又会回调到 ActiveServices 的 attachApplicationLocked。

5.1 attachApplicationLocked

    boolean attachApplicationLocked(ProcessRecord proc, String processName)
            throws RemoteException {
        boolean didSomething = false;
        // mPendingServices 便是咱们之前添加的服务,这儿取出来
        if (mPendingServices.size() > 0) {
            ServiceRecord sr = null;
            try {
                for (int i=0; i<mPendingServices.size(); i++) {
                    sr = mPendingServices.get(i);
                    ... // 省掉代码
		            // 发动服务后边的流程 [见4.4]
                    realStartServiceLocked(sr, proc, thread, pid, uidRecord, sr.createdFromFg,
                            true);
                    didSomething = true;
                    ...
                }
            } catch (RemoteException e) {
                throw e;
            }
        }
        ... // 省掉代码
        return didSomething;
    }

可见,假如 Service 地点的进程没有发动,在进程发动后,依旧会走 realStartServiceLocked 这条服务发动的流程。

六 startService 小结

到这儿,startService 服务的发动流程现已走完了,尽管出现了几种不同的场景,不过体系的大致思路咱们能够总结一下

  1. 首先是参数判别和权限的判别,各种权限判别服务是否能够发动,是否需求中止等等
  2. 然后便是复用的判别,判别是否有 ServiceRecord 能够复用
  3. 最终便是进程的判别,是否现已发动,然后依据已发动和未发动做相应的流程
  4. 然后再通过一条延迟音讯,判别服务发动是否会 ANR

七 bindService

前面说了 startService 的流程,接下来咱们说说 bindService。 bindService 也是从 ComtextImpl 开端,分别调用

  • ComtextImpl.bindService
  • ComtextImpl.bindServiceCommon
  • ActivityManagerService.bindIsolatedService

八 ActivityManagerService

8.1 bindIsolatedService

public int bindIsolatedService(IApplicationThread caller, IBinder token, Intent service,
		String resolvedType, IServiceConnection connection, int flags, String instanceName,
		String callingPackage, int userId) throws TransactionTooLargeException {
	... // 省掉代码
	synchronized(this) {
		return mServices.bindServiceLocked(caller, token, service,
				resolvedType, connection, flags, instanceName, callingPackage, userId);
	}
}

九 ActiveServices

9.1 bindServiceLocked

bindServiceLocked 这个函数十分长,所以我省掉了大部分代码只保留了骨干代码。

int bindServiceLocked(IApplicationThread caller, IBinder token, Intent service,
		String resolvedType, final IServiceConnection connection, int flags,
		String instanceName, String callingPackage, final int userId)
		throws TransactionTooLargeException {
	final int callingPid = Binder.getCallingPid();
	final int callingUid = Binder.getCallingUid();
	final ProcessRecord callerApp = mAm.getRecordForAppLOSP(caller);
	ActivityServiceConnectionsHolder<ConnectionRecord> activity = null;
	if (token != null) {
		// mAtmInternal 其实便是 ActivityTaskManagerService
		// 这儿拿到的 ActivityServiceConnectionsHolder 其实便是
		// activity 和 service 的数据组合
		activity = mAm.mAtmInternal.getServiceConnectionsHolder(token);
		if (activity == null) {
			return 0;
		}
	}
	... //  这儿省掉大段的权限判别
	// 检索服务信息 [见9.3]
	ServiceLookupResult res =
		retrieveServiceLocked(service, instanceName, resolvedType, callingPackage,
				callingPid, callingUid, userId, true,
				callerFg, isBindExternal, allowInstant);
	if (res == null) {
		return 0;
	}
	if (res.record == null) {
		return -1;
	}
	ServiceRecord s = res.record;
	... // 省掉代码
	try {
		... // 省掉代码
		// 即将绑定的 Service 添加到 AppBindRecord 调集 [见9.2]
		AppBindRecord b = s.retrieveAppBindingLocked(service, callerApp);
		ConnectionRecord c = new ConnectionRecord(b, activity,
				connection, flags, clientLabel, clientIntent,
				callerApp.uid, callerApp.processName, callingPackage);
		IBinder binder = connection.asBinder();
		s.addConnection(binder, c);
		b.connections.add(c);
		if (activity != null) {
			activity.addConnection(c);
		}
		final ProcessServiceRecord clientPsr = b.client.mServices;
		clientPsr.addConnection(c);
		c.startAssociationIfNeeded();
		... // 省掉代码
		// 假如
		if ((flags&Context.BIND_AUTO_CREATE) != 0) {
			s.lastActivity = SystemClock.uptimeMillis();
			needOomAdj = true;
			// 假如 Service 没有发动,但是又有主动创建的标志
			// BIND_AUTO_CREATE
			// 那么久会触发 Service 的发动流程 [见4.3]
			if (bringUpServiceLocked(s, service.getFlags(), callerFg, false,
					permissionsReviewRequired, packageFrozen, true) != null) {
				mAm.updateOomAdjPendingTargetsLocked(OomAdjuster.OOM_ADJ_REASON_BIND_SERVICE);
				return 0;
			}
		}
		... // 省掉代码
		if (s.app != null && b.intent.received) {
			try {
				// 服务现已发动起来了,咱们调用 connected 函数
				c.conn.connected(s.name, b.intent.binder, false);
			} catch (Exception e) {
			}
		... // 省掉代码
	return 1;
}

在 bindServiceLocked 函数中,主要做了这样几件事

  • 将 Activity 和 Service 关联,保存在 ActivityServiceConnectionsHolder 中
  • 假如有 BIND_AUTO_CREATE 标志,而且服务部存在就会创建服务
  • 通过 connected 调用 Service 的 onServiceConnected 函数

9.2 retrieveAppBindingLocked

public AppBindRecord retrieveAppBindingLocked(Intent intent,
		ProcessRecord app) {
	// 将 intent 封装成一个 Intent.FilterComparison
	// 并将 filter 保存到 bindings 这个 Map 调集中
	Intent.FilterComparison filter = new Intent.FilterComparison(intent);
	IntentBindRecord i = bindings.get(filter);
	if (i == null) {
		i = new IntentBindRecord(this, filter);
		bindings.put(filter, i);
	}
	AppBindRecord a = i.apps.get(app);
	if (a != null) {
		return a;
	}
	a = new AppBindRecord(this, i, app);
	i.apps.put(app, a);
	return a;
}

ActiveService 中有一个 bindings 成员变量,它是一个 Map 调集,保存了 Intent 和 IntentBindRecord 的关系。这个 Intent 便是要绑定的 Service。

9.3 requestServiceBindingsLocked

private final void requestServiceBindingsLocked(ServiceRecord r, boolean execInFg) throws TransactionTooLargeException {
	for (int i=r.bindings.size()-1; i>=0; i--) {
		IntentBindRecord ibr = r.bindings.valueAt(i);
		// 从 ServiceRecord 中取出 IntentBindRecord
		// 然后再调用 requestServiceBindingLocked
		if (!requestServiceBindingLocked(r, ibr, execInFg, false)) {
			break;
		}
	}
}

在 requestServiceBindingsLocked 中,会取出 bindings 里保存的 IntentBindRecord,然后分别调用 requestServiceBindingLocked 进行绑定。

9.4 requestServiceBindingLocked

private final boolean requestServiceBindingLocked(ServiceRecord r, IntentBindRecord i,
		boolean execInFg, boolean rebind) throws TransactionTooLargeException {
	if ((!i.requested || rebind) && i.apps.size() > 0) {
		try {
			bumpServiceExecutingLocked(r, execInFg, "bind",
					OomAdjuster.OOM_ADJ_REASON_BIND_SERVICE);
			// 调用 ActivityThread 的 scheduleBindService
			// 最终会调用到 Service 的 onBind
			r.app.getThread().scheduleBindService(r, i.intent.getIntent(), rebind,
					r.app.mState.getReportedProcState());
			if (!rebind) {
				i.requested = true;
			}
			i.hasBound = true;
			i.doRebind = false;
		} catch (TransactionTooLargeException e) {
			...
		}
	}
	return true;
}

在 requestServiceBindingLocked 中,会调用 r.app.getThread 拿到 ActivityThread,然后调用 scheduleBindService,这个函数会通过音讯机制进行如下调用。

  • ActivityThread.scheduleBindService
  • ActivityThread.handleBindService
  • Service.onBind

这部分比较简略,这儿就不具体扩展了。

总结

最终再来总结一下 Service 的发动流程,Service 的发动分为两种

  • 第一种是 activity.startService
  • 第二种是 activity.bindService

当然,不论是哪一种,整个进程会有四个进程参与,一个是 App 进程,一个是 AMS 地点是进程(system_server 进程),还有一个便是 Zygote 进程,最终则是 Service 地点进程。

对应 startService,整体的发动流程如下

  1. APP 进程发起 startService 的恳求,然后通过一下调用
    1. ContextWrapper.startService
    2. ContextImpl.startService
    3. ContextImpl.startServiceCommon
    4. 接下来进入 AMS 地点的 system_server 进程
  2. 在 AMS 中,有一个专门用于服务相关的类 ActiveServices 进行处理,大致的处理流程如下
    1. 服务的判别(前台仍是后台)
    2. 权限的判别
    3. 发动服务(又分为 Service 地点的进程已发动仍是未发动)
      1. 进程未发动:先发动进程,将服务添加到 mPendingServices 中。然后在进程发动后的 attachApplicationLocked 中发动服务
      2. 进程已发动,直接发动服务
    4. 发送延迟音讯判别 ANR
  3. 在 Service 进程的 ActivityThread 中,通过音讯机制,切换线程,并回调到 Service 的生命周期函数

流程图如下

Service启动源码解析(Android12)

关于 bindService,整体流程如下

  1. APP 进程发起 bindService 的恳求,然后通过一下调用
    1. ContextWrapper.bindService
    2. ContextImpl.bindService
    3. ContextImpl.bindServiceCommon
    4. 接下来进入 AMS 地点的 system_server 进程
  2. 在 AMS 中,有一个专门用于服务相关的类 ActiveServices 进行处理,大致的处理流程如下
    1. 服务的判别(前台仍是后台),权限的判别和发动服务的逻辑都和 startService 一样
    2. bindService 会将 Service 和 Activity 封装到一个对应的数据结构 ConnectionRecord 中
    3. 要绑定的 Service 会保存到 ActiveServices 的成员变量 bindings 中,方便后续调用生命周期 onBind
  3. 在 Service 进程的 ActivityThread 中,通过音讯机制,切换线程,并回调到 Service 的生命周期 onBind 函数

流程图如下

Service启动源码解析(Android12)