本文基于aosp8.0源码分析
Service的启动 Service
的启动分两种,一种startService
,另一种bindService
StartService 一般我们会在Activity
中通过startService
来启动一个服务
Activity.startService 其内部实际上是由ContextWrapper
的startService
来启动,实际启动的地方是在ContextImpl.startService
ContextImpl.startService 1 2 3 4 5 @Override public ComponentName startService (Intent service) { warnIfCallingFromSystemProcess(); return startServiceCommon(service, false , mUser); }
ContextImpl.startServiceCommon 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 private ComponentName startServiceCommon (Intent service, boolean requireForeground, UserHandle user) { try { validateServiceIntent(service); service.prepareToLeaveProcess(this ); ComponentName cn = ActivityManager.getService().startService( mMainThread.getApplicationThread(), service, service.resolveTypeIfNeeded( getContentResolver()), requireForeground, getOpPackageName(), 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 new IllegalStateException ( "Not allowed to start service " + service + ": " + cn.getClassName()); } } return cn; } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } }
这里首选需要验证服务,5.0之后隐世服务就不被允许,何为隐世,未指定包名,未指定类名
1 2 3 public static IActivityManager getService () { return IActivityManagerSingleton.get(); }
从ServiceManager
中获取ActivityManager
的IBinder
对象
通过IPC
获取了ActivityManagerService
对象
每个系统服务都采用了AIDL
的方式进行,不直接对外暴露代理
IActivityManager.aidl 该文件对应的native
实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 class BpActivityManager : public BpInterface<IActivityManager>{ public : explicit BpActivityManager (const sp<IBinder>& impl) : BpInterface<IActivityManager>(impl) { } virtual int openContentUri (const String16& stringUri) { Parcel data, reply; data.writeInterfaceToken (IActivityManager::getInterfaceDescriptor ()); data.writeString16 (stringUri); status_t ret = remote ()->transact (OPEN_CONTENT_URI_TRANSACTION, data, & reply); int fd = -1 ; if (ret == NO_ERROR) { int32_t exceptionCode = reply.readExceptionCode (); if (!exceptionCode) { if (reply.readInt32 () != 0 ) { fd = fcntl (reply.readParcelFileDescriptor (), F_DUPFD_CLOEXEC, 0 ); } } else { ALOGD ("openContentUri(%s) caught exception %d\n" , String8 (stringUri).string (), exceptionCode); } } return fd; } };
ActivityManagerService.startService 1 2 3 4 5 6 7 8 9 10 11 12 public class ActivityManagerService extends IActivityManager .Stub {@Override public ComponentName startService (IApplicationThread caller, Intent service, String resolvedType, boolean requireForeground, String callingPackage, int userId) throws TransactionTooLargeException { ... res = mServices.startServiceLocked(caller, service, resolvedType, callingPid, callingUid, requireForeground, callingPackage, userId); ... } }
ActivityManagerService
就是ActivityManager
定义的AIDL
的具体实现
调用ActiveServices.startServiceLocked
ActiveServices.startServiceLocked 1 2 3 4 5 6 7 8 ComponentName startServiceLocked (IApplicationThread caller, Intent service, String resolvedType, int callingPid, int callingUid, boolean fgRequired, String callingPackage, final int userId) throws TransactionTooLargeException { ... ComponentName cmp = startServiceInnerLocked(smap, service, r, callerFg, addToStarting); ... }
检查Service
调用者合法性。创建并缓存Service
信息
ActiveServices.startServiceInnerLocked 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 ComponentName startServiceInnerLocked (ServiceMap smap, Intent service, ServiceRecord r, boolean callerFg, boolean addToStarting) throws TransactionTooLargeException { ServiceState stracker = r.getTracker(); if (stracker != null ) { stracker.setStarted(true , mAm.mProcessStats.getMemFactorLocked(), r.lastActivity); } r.callStart = false ; synchronized (r.stats.getBatteryStats()) { r.stats.startRunningLocked(); } String error = bringUpServiceLocked(r, service.getFlags(), callerFg, false , false ); if (error != null ) { return new ComponentName ("!!" , error); } if (r.startRequested && addToStarting) { boolean first = smap.mStartingBackground.size() == 0 ; smap.mStartingBackground.add(r); r.startingBgTimeout = SystemClock.uptimeMillis() + mAm.mConstants.BG_START_TIMEOUT; if (DEBUG_DELAYED_SERVICE) { RuntimeException here = new RuntimeException ("here" ); here.fillInStackTrace(); Slog.v(TAG_SERVICE, "Starting background (first=" + first + "): " + r, here); } else if (DEBUG_DELAYED_STARTS) { Slog.v(TAG_SERVICE, "Starting background (first=" + first + "): " + r); } if (first) { smap.rescheduleDelayedStartsLocked(); } } else if (callerFg || r.fgRequired) { smap.ensureNotStartingBackgroundLocked(r); } return r.name; }
调用bringUpServiceLocked
,处理返回结果
ActiveService.bringUpServiceLocked 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 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 ; } ... app = mAm.getProcessRecordLocked(procName, r.appInfo.uid, false ); if (DEBUG_MU) Slog.v(TAG_MU, "bringUpServiceLocked: appInfo.uid=" + r.appInfo.uid + " app=" + app); 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); } } ... }
如果服务已经启动,调用sendserviceArgsLocked
。首次创建。获取进程信息。调用realStartServiceLocked
ActiveServices.realStartServiceLocked 1 2 3 4 5 6 7 8 9 10 11 12 13 private final void realStartServiceLocked (ServiceRecord r, ProcessRecord app, boolean execInFg) throws RemoteException { ... final boolean newService = app.services.add(r); ... ... app.thread.scheduleCreateService(r, r.serviceInfo, mAm.compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo), app.repProcState); ... sendServiceArgsLocked(r, execInFg, true ); }
更新服务优先级。通知ApplicationThread
创建启动Service
。之后调用sendServiceArgsLocked
,其作用,处理Service
参数,并回调onStartCommand
ActivityThread.scheduleCreateService 1 2 3 4 5 6 7 8 9 10 public final void scheduleCreateService (IBinder token, ServiceInfo info, CompatibilityInfo compatInfo, int processState) { updateProcessState(processState, false ); CreateServiceData s = new CreateServiceData (); s.token = token; s.info = info; s.compatInfo = compatInfo; sendMessage(H.CREATE_SERVICE, s); }
BindService bindService
的流程,跟startService
很相似。
ActiveServices.bindServiceLocked 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 int bindServiceLocked (IApplicationThread caller, IBinder token, Intent service, String resolvedType, final IServiceConnection connection, int flags, String callingPackage, final int userId) throws TransactionTooLargeException { ... ArrayList<ConnectionRecord> clist = s.connections.get(binder); if (clist == null ) { clist = new ArrayList <ConnectionRecord>(); s.connections.put(binder, clist); } clist.add(c); b.connections.add(c); if (activity != null ) { if (activity.connections == null ) { activity.connections = new HashSet <ConnectionRecord>(); } activity.connections.add(c); } b.client.connections.add(c); ... if ((flags&Context.BIND_AUTO_CREATE) != 0 ) { s.lastActivity = SystemClock.uptimeMillis(); if (bringUpServiceLocked(s, service.getFlags(), callerFg, false , permissionsReviewRequired) != null ) { return 0 ; } } ... }
ServiceRecord
存储每个Binder
,也就是ServiceConnection
。内部的数据结构都是Set
,确保Binder
唯一。调用bringUpServiceLocked
ActiveServices.bringUpServiceLocked 1 2 3 4 5 private String bringUpServiceLocked (ServiceRecord r, int intentFlags, boolean execInFg, boolean whileRestarting, boolean permissionsReviewRequired) throws TransactionTooLargeException { }
首次绑定Service
的过程和startService
一样。也是调用realStartServiceLocked
。非首次也是调用sendServiceArgsLocked
,这个函数中,如果有startService
的话,那么会发出消息通知ApplicationThread
需要处理onStartCommand
。BindService
下,会直接返回
1 2 3 4 5 6 7 8 private final void realStartServiceLocked (ServiceRecord r, ProcessRecord app, boolean execInFg) throws RemoteException { ... ... requestServiceBindingsLocked(r, execInFg); }
创建过程一样。创建完之后会检查是否有Binder
。如果有直接通知ApplicationThread
需要绑定服务。
总结 客户端发起启动服务请求,通过IPC
的方式通知SystemServer
进程中的ActivityManagerService
,然后通知ApplicationThread
创建服务
时序图 StartService
BindService