现在的位置: 首页 > 综合 > 正文

Android服务启动之StartService源码分析

2014年10月06日 ⁄ 综合 ⁄ 共 23322字 ⁄ 字号 评论关闭

在编写Android应用程序时,我们一般将比较耗时的操作放在一个独立的进程来处理,这样主进程仍然可以流畅地响应界面事件,提高用户体验。Android系统为我们提供了一个Service类,我们可以实现一个以Service为基类的服务子类,在里面实现自己的计算型逻辑,然后在主进程通过startService函数来启动这个服务。在本文中,将详细分析应用程序进程是如何通过startService函数来启动自定义服务的。

请求启动Service

frameworks\base\core\java\android\content\Context.java

public abstract ComponentName startService(Intent service);

在Context类中定义了抽象方法startService,该函数由Context的子类ContextImpl实现。

frameworks\base\core\java\android\content\ContextWrapper.java

public ComponentName startService(Intent service) {
	return mBase.startService(service);
}

mBase为ContextImpl类型对象

frameworks\base\core\java\android\app\ContextImpl.java

public ComponentName startService(Intent service) {
	try {
		service.setAllowFds(false);
		//调用ActivityManagerService服务的Binder远程代理发送启动Service的参数
		ComponentName cn = ActivityManagerNative.getDefault().startService(
			mMainThread.getApplicationThread(), service,
			service.resolveTypeIfNeeded(getContentResolver()));
		if (cn != null && cn.getPackageName().equals("!")) {
			throw new SecurityException(
					"Not allowed to start service " + service
					+ " without permission " + cn.getClassName());
		}
		return cn;
	} catch (RemoteException e) {
		return null;
	}
}

ActivityManagerNative.getDefault()将得到ActivityManagerProxy对象,参数mMainThread.getApplicationThread()表示为当前启动服务进程的ApplicationThread对象,参数service.resolveTypeIfNeeded(getContentResolver())返回当前传输的Intent的MEMI号,关于Binder进程间RPC调用过程这里不在详细分析,有兴趣可以参考Android服务函数远程调用源码分析。通过ActivityManagerNative.getDefault().startService()调用,将Service的启动交给SystemServer进程的ActivityManagerService服务来完成。

frameworks\base\services\java\com\android\server\am\ActivityManagerService.java

public ComponentName startService(IApplicationThread caller, Intent service,
		String resolvedType) {
	// Refuse possible leaked file descriptors
	if (service != null && service.hasFileDescriptors() == true) {
		throw new IllegalArgumentException("File descriptors passed in Intent");
	}

	synchronized(this) {
		//读取启动服务的应用程序进程的PID和UID
		final int callingPid = Binder.getCallingPid();
		final int callingUid = Binder.getCallingUid();
		final long origId = Binder.clearCallingIdentity();
		ComponentName res = startServiceLocked(caller, service,
				resolvedType, callingPid, callingUid);
		Binder.restoreCallingIdentity(origId);
		return res;
	}
}

参数caller是启动服务的应用程序进程的ApplicationThread实例,比如说Launcher启动服务,那么这个caller就是Launcher进程的ApplicationThread实例,每一个Android应用程序进程都有且只有一个ActivityThread实例,每一个ActivityThread实例中又定义了一个ApplicationThread对象。接下来调用startServiceLocked函数来启动服务

frameworks/base/services/java/com/android/server/am/ActivityManagerService.java

ComponentName startServiceLocked(IApplicationThread caller,
		Intent service, String resolvedType,
		int callingPid, int callingUid) {
	synchronized(this) {
		if (DEBUG_SERVICE) Slog.v(TAG, "startService: " + service
				+ " type=" + resolvedType + " args=" + service.getExtras());
		if (caller != null) {
			//通过ApplicationThread对象从ActivityManagerService的成员变量mLruProcesses列表中查找启动服务的进程在ActivityManagerService中的ProcessRecord对象,变量mLruProcesses的说明:
			 /**
			 * List of running applications, sorted by recent usage.
			 * The first entry in the list is the least recently used.
			 * It contains ApplicationRecord objects.  This list does NOT include
			 * any persistent application records (since we never want to exit them).
			 */
			final ProcessRecord callerApp = getRecordForAppLocked(caller);
			if (callerApp == null) {
				throw new SecurityException(
						"Unable to find app for caller " + caller
						+ " (pid=" + Binder.getCallingPid()
						+ ") when starting service " + service);
			}
		}
        //解析service这个Intent
         /**
         * private final class ServiceLookupResult {
		 *		final ServiceRecord record; ServiceRecord用于在服务端描述一个Service信息
		 *		final String permission;
		 *		ServiceLookupResult(ServiceRecord _record, String _permission) {
		 *			record = _record;
		 *			permission = _permission;
		 *		}
		 * };
         */
		ServiceLookupResult res = retrieveServiceLocked(service, resolvedType,
					callingPid, callingUid, UserId.getUserId(callingUid));
		//系统中没有注册此Service
		if (res == null) {
			return null;
		}
		if (res.record == null) {
			return new ComponentName("!", res.permission != null ? res.permission : "private to package");
		}
		//权限检查
		ServiceRecord r = res.record;
		NeededUriGrants neededGrants = checkGrantUriPermissionFromIntentLocked(
				callingUid, r.packageName, service, service.getFlags(), null);
		if (unscheduleServiceRestartLocked(r)) {
			if (DEBUG_SERVICE) Slog.v(TAG, "START SERVICE WHILE RESTART PENDING: " + r);
		}
		//初始化服务端的ServiceRecord信息
		r.startRequested = true;
		r.callStart = false;
		r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
				service, neededGrants));
		r.lastActivity = SystemClock.uptimeMillis();
		synchronized (r.stats.getBatteryStats()) {
			r.stats.startRunningLocked();
		}
		//进一步启动Service
		if (!bringUpServiceLocked(r, service.getFlags(), false)) {
			return new ComponentName("!", "Service process is bad");
		}
		return r.name;
	}
}

ActivityManagerService在请求Zygote进程孵化新的应用程序进程时,在ActivityManagerService服务端为每一个应用程序进程创建了对应的ProcessRecord对象来描述新的应用程序进程信息,关于ActivityManagerService请求孵化新应用程序过程请参考Android
应用进程启动过程的源码分析
。函数首先根据应用程序进程中的IApplicationThread对象在最近启动的应用程序列表mLruProcesses中为服务启动进程查找对应的ProcessRecord对象,如果启动Service的应用程序进程还未启动,则抛出SecurityException异常。然后调用retrieveServiceLocked函数为当前启动的Service在ActivityManagerService服务端创建一个ServiceRecord对象来描述当前Service的信息。

frameworks/base/services/java/com/android/server/am/ActivityManagerService.java

private ServiceLookupResult retrieveServiceLocked(Intent service,
		String resolvedType, int callingPid, int callingUid, int userId) {
	ServiceRecord r = null;
	if (DEBUG_SERVICE)
		Slog.v(TAG, "retrieveServiceLocked: " + service + " type=" + resolvedType
				+ " callingUid=" + callingUid);
	//根据Service的包名从ActivityManagerService的成员变量mServiceMap中查找对应的ServiceRecord对象
	if (service.getComponent() != null) {
		r = mServiceMap.getServiceByName(service.getComponent(), userId);
	}
	//根据启动Service的Intent信息从成员变量mServiceMap中查找对应的ServiceRecord对象
	if (r == null) {
		Intent.FilterComparison filter = new Intent.FilterComparison(service);
		r = mServiceMap.getServiceByIntent(filter, userId);
	}
	//如果mServiceMap中不存在当前启动的Service对应的ServiceRecord对象
	if (r == null) {
		try {
			//从PackageManager服务中获取当前启动Service的相关信息,并构造ResolveInfo对象
			ResolveInfo rInfo =AppGlobals.getPackageManager().resolveService(
							service, resolvedType, STOCK_PM_FLAGS, userId);
			//获取Service信息对象
			ServiceInfo sInfo = rInfo != null ? rInfo.serviceInfo : null;
			if (sInfo == null) {
				Slog.w(TAG, "Unable to start service " + service +
					  ": not found");
				return null;
			}
			if (userId > 0) {
				if (isSingleton(sInfo.processName, sInfo.applicationInfo)) {
					userId = 0;
				}
				sInfo.applicationInfo = getAppInfoForUser(sInfo.applicationInfo, userId);
			}
			ComponentName name = new ComponentName(
					sInfo.applicationInfo.packageName, sInfo.name);
			//再次根据Service的包名从成员变量mServiceMap中查找对应的ServiceRecord对象
			r = mServiceMap.getServiceByName(name, userId);
			//依然查找不到
			if (r == null) {
				Intent.FilterComparison filter = new Intent.FilterComparison(
						service.cloneFilter());
				//为当前Service构造一个重启服务的Runnable对象
				ServiceRestarter res = new ServiceRestarter();
				BatteryStatsImpl.Uid.Pkg.Serv ss = null;
				BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
				synchronized (stats) {
					ss = stats.getServiceStatsLocked(
							sInfo.applicationInfo.uid, sInfo.packageName,
							sInfo.name);
				}
				//为当前Service构造ServiceRecord对象
				r = new ServiceRecord(this, ss, name, filter, sInfo, res);
				//设置ServiceRestarter重启的服务为当前Service
				res.setService(r);
				//将当前Service的服务端描述符ServiceRecord保存到mServiceMap中
				mServiceMap.putServiceByName(name, UserId.getUserId(r.appInfo.uid), r);
				mServiceMap.putServiceByIntent(filter, UserId.getUserId(r.appInfo.uid), r);
				//通过服务名称查找mPendingServices服务列表中是否存在当前Service
				int N = mPendingServices.size();
				for (int i=0; i<N; i++) {
					ServiceRecord pr = mPendingServices.get(i);
					if (pr.name.equals(name)) {
						mPendingServices.remove(i);
						i--;
						N--;
					}
				}
			}
		} catch (RemoteException ex) {
			// pm is in same process, this will never happen.
		}
	}
	if (r != null) {
		//检查服务权限
		if (checkComponentPermission(r.permission,
				callingPid, callingUid, r.appInfo.uid, r.exported)
				!= PackageManager.PERMISSION_GRANTED) {
			if (!r.exported) {
				Slog.w(TAG, "Permission Denial: Accessing service " + r.name
						+ " from pid=" + callingPid
						+ ", uid=" + callingUid
						+ " that is not exported from uid " + r.appInfo.uid);
				return new ServiceLookupResult(null, "not exported from uid "
						+ r.appInfo.uid);
			}
			Slog.w(TAG, "Permission Denial: Accessing service " + r.name
					+ " from pid=" + callingPid
					+ ", uid=" + callingUid
					+ " requires " + r.permission);
			return new ServiceLookupResult(null, r.permission);
		}
		//返回ServiceLookupResult对象
		return new ServiceLookupResult(r, null);
	}
	return null;
}

该函数通过一系列处理后,为当前启动的Service构造了对应的ServiceRecord对象,并保存到ActivityManagerService的成员变量mServiceMap中,这样就相当于在ActivityManagerService服务端完成了服务登记工作,接下来将调用bringUpServiceLocked函数正式启动这个已经记录在案的Service。

frameworks/base/services/java/com/android/server/am/ActivityManagerService.java

private final boolean bringUpServiceLocked(ServiceRecord r,
		int intentFlags, boolean whileRestarting) {
	//如果该Service服务已经创建,再次调用startService时,只调用该Service的onStartCommand来运行该Service
	if (r.app != null && r.app.thread != null) {
		//启动Service
		sendServiceArgsLocked(r, false);
		return true;
	}
	if (!whileRestarting && r.restartDelay > 0) {
		// If waiting for a restart, then do nothing.
		return true;
	}
	if (DEBUG_SERVICE) Slog.v(TAG, "Bringing up " + r + " " + r.intent);
	// 将当前启动的Service从服务重启列表mRestartingServices中移除
	mRestartingServices.remove(r);
	// Service is now being launched, its package can't be stopped.
	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);
	}
	//判断此Service是否在独立的进程中启动
	final boolean isolated = (r.serviceInfo.flags&ServiceInfo.FLAG_ISOLATED_PROCESS) != 0;
	//得到在XML中设置该Service运行的进程名称
	final String appName = r.processName;
	ProcessRecord app;
	//当前Service运行在应用程序进程,并非独立进程
	if (!isolated) {
		//根据进程名称及UID从ActivityManagerService的成员变量mProcessNames中查找进程对应的描述符ProcessRecord
		app = getProcessRecordLocked(appName, r.appInfo.uid);
		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);
				//在现有的进程中启动Service
				realStartServiceLocked(r, app);
				return true;
			} catch (RemoteException e) {
				Slog.w(TAG, "Exception when starting service " + r.shortName, e);
			}
		}
	} else {
		// If this service runs in an isolated process, then each time
		// we call startProcessLocked() we will get a new isolated
		// process, starting another process if we are currently waiting
		// for a previous process to come up.  To deal with this, we store
		// in the service any current isolated process it is running in or
		// waiting to have come up.
		app = r.isolatedProc;
	}
	// Not running -- get it started, and enqueue this service record
	// to be executed when the app comes up.
	if (app == null) {
		//启动应用程序进程
		if ((app=startProcessLocked(appName, r.appInfo, true, intentFlags,
				"service", r.name, false, isolated)) == null) {
			Slog.w(TAG, "Unable to launch app "
					+ r.appInfo.packageName + "/"
					+ r.appInfo.uid + " for service "
					+ r.intent.getIntent() + ": process is bad");
			//强制退出Service
			bringDownServiceLocked(r, true);
			return false;
		}
		if (isolated) {
			r.isolatedProc = app;
		}
	}
	//当ActivityManagerService服务还为准备好时,mPendingServices用于保存客户进程请求启动的Servcie
	//保存当前请求启动的Service
	if (!mPendingServices.contains(r)) {
		mPendingServices.add(r);
	}
	return true;
}

如果当前系统中已经存在运行该Service的进程,则调用函数realStartServiceLocked来进一步启动Service,realStartServiceLocked函数的第一个参数是当前启动的Service在ActivityManagerService服务中的描述符对象ServiceRecord,第二个参数则是运行该Service的进程在ActivityManagerService服务中的描述符对象ProcessRecord,有了启动的Service和运行该Service的进程,接下来就可以真正启动该Service了。

frameworks/base/services/java/com/android/server/am/ActivityManagerService.java

private final void realStartServiceLocked(ServiceRecord r,ProcessRecord app) throws  RemoteException {
	if (app.thread == null) {
		throw new RemoteException();
	}
	if (DEBUG_MU)
		Slog.v(TAG_MU, "realStartServiceLocked, ServiceRecord.uid = " + r.appInfo.uid
				+ ", ProcessRecord.uid = " + app.uid);
	// LC_RAM_SUPPORT
	if (LC_RAM_SUPPORT) {
		r.appAdj = ProcessRecord.TMP_CUR_ADJ_DEFAULT;
		r.hasFixAdj = (app.fixAdj != ProcessRecord.TMP_FIX_ADJ_DEFAULT);
	}
	r.app = app;
	r.restartTime = r.lastActivity = SystemClock.uptimeMillis();
	//在ActivityManagerService服务中记录当前进程中运行的所有Service
	app.services.add(r);
	bumpServiceExecutingLocked(r, "create");
	//mLruProcesses保存系统最近运行的应用程序进程信息,更新当前ProcessRecord在mLruProcesses变量中的状态
	updateLruProcessLocked(app, true, true);
	boolean created = false;
	try {
		mStringBuilder.setLength(0);
		r.intent.getIntent().toShortString(mStringBuilder, true, false, true, false);
		EventLog.writeEvent(EventLogTags.AM_CREATE_SERVICE,
				System.identityHashCode(r), r.shortName,
				mStringBuilder.toString(), r.app.pid);
		synchronized (r.stats.getBatteryStats()) {
			r.stats.startLaunchedLocked();
		}
		//检查当前Service所在包是否经过Dex优化过
		ensurePackageDexOpt(r.serviceInfo.packageName);
		//创建Service服务
		app.thread.scheduleCreateService(r, r.serviceInfo,compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo));
		r.postNotification();
		created = true;
	} finally {
		if (!created) {
			app.services.remove(r);
			scheduleServiceRestartLocked(r, false);
		}
	}
	//绑定该Service服务
	requestServiceBindingsLocked(r);
	// If the service is in the started state, and there are no
	// pending arguments, then fake up one so its onStartCommand() will
	// be called.
	if (r.startRequested && r.callStart && r.pendingStarts.size() == 0) {
		r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
				null, null));
	}
	//启动该Service服务
	sendServiceArgsLocked(r, true);
}

在该函数中完成了Service的创建,Service的绑定,Service的启动。无论是Service的创建,绑定还是启动过程,都是由ActivityManagerService服务调度应用程序进程来完成的,通过Binder跨进程调用来实现。在此之前Service启动的前期工作都是在ActivityManagerService中完成,主要是实现Service的备案:

Service创建过程

ActivityManagerService通过Binder跨进程调用应用程序进程中的ApplicationThread的scheduleCreateService函数在应用程序进程中加载Service类,并创建Service对象。
frameworks\base\core\java\android\app\ActivityThread.$ApplicationThread
public final void scheduleCreateService(IBinder token,
		ServiceInfo info, CompatibilityInfo compatInfo) {
	CreateServiceData s = new CreateServiceData();
	s.token = token;//ServiceRecord Binder本地对象
	s.info = info;
	s.compatInfo = compatInfo;
	queueOrSendMessage(H.CREATE_SERVICE, s);
}

在ActivityThread类中定义了一个内部类H,继承于Handler,在Android应用程序进程启动过程中,我们介绍了Zygote进程通过复制一份自身进程地址空间来实现子进程的创建过程,孵化出来新的应用程序进程通过加载ActivityThread类,并调用该类的main函数为应用程序主线程建立消息循环,而定义的H这个Handler正是向主线程消息循环发送消息的通道,在这个函数中,将ActivityManagerService服务通过Binder跨进程调用Service运行进程的scheduleCreateService函数转换为本地的一个异步调用。在该函数中,将函数调用参数信息封装为CreateServiceData对象,然后通过queueOrSendMessage函数向应用程序主线程消息循环中发送一个CREATE_SERVICE消息,在H的handleMessage()函数中,完成对该消息的处理:

frameworks\base\core\java\android\app\ActivityThread.$H
public void handleMessage(Message msg) {
	if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
	switch (msg.what) {
	case CREATE_SERVICE:
		Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceCreate");
		handleCreateService((CreateServiceData)msg.obj);
		Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
		break;
	}
}

这里又将Service的创建工作交给H的外部类ActivityThread的handleCreateService()函数来完成。

frameworks\base\core\java\android\app\ActivityThread.java
private void handleCreateService(CreateServiceData data) {
	// If we are getting ready to gc after going to the background, well
	// we are back active so skip it.
	unscheduleGcIdler();
	//加载启动的Service类
	LoadedApk packageInfo = getPackageInfoNoCheck(data.info.applicationInfo, data.compatInfo);
	Service service = null;
	try {
		java.lang.ClassLoader cl = packageInfo.getClassLoader();
		service = (Service) cl.loadClass(data.info.name).newInstance();
	} catch (Exception e) {
		if (!mInstrumentation.onException(service, e)) {
			throw new RuntimeException(
				"Unable to instantiate service " + data.info.name
				+ ": " + e.toString(), e);
		}
	}
	try {
		if (localLOGV) Slog.v(TAG, "Creating service " + data.info.name);
		//为该Service创建一个上下文ContextImpl对象
		ContextImpl context = new ContextImpl();
		context.init(packageInfo, null, this);

		Application app = packageInfo.makeApplication(false, mInstrumentation);
		context.setOuterContext(service);
		//将Application,ActivityManagerService,当前Service在SystemServer进程中的ServiceRecord引用保存到当前Service的成员变量中
		service.attach(context, this, data.info.name, data.token, app,ActivityManagerNative.getDefault());
		//回调当前启动Service的onCreate函数
		service.onCreate();
		//变量mServices保存了应用程序进程中运行的所有Service
		mServices.put(data.token, service);
		//从应用程序进程进入SystemServer进程
		try {
			//通知ActivityManagerService服务,当前Service创建完成
			ActivityManagerNative.getDefault().serviceDoneExecuting(data.token, 0, 0, 0);
		} catch (RemoteException e) {
			// nothing to do.
		}
	} catch (Exception e) {
		if (!mInstrumentation.onException(service, e)) {
			throw new RuntimeException(
				"Unable to create service " + data.info.name
				+ ": " + e.toString(), e);
		}
	}
}

在前面我们已经知道当前启动的Service在ActivityManagerService中已经记录在mServiceMap成员变量中了,对于运行Service的应用程序进程来说,仍然需要记录该进程中运行的Service信息,并保存在ActivityThread的成员变量mServices中。在该函数中加载启动Service的类,并为Service创建一个上下文对象,同时回调Service的onCreate()函数完成Service的创建过程。

Service绑定过程

frameworks/base/services/java/com/android/server/am/ActivityManagerService.java
private final void requestServiceBindingsLocked(ServiceRecord r) {
	//遍历当前Service的成员变量bindings
	Iterator<IntentBindRecord> bindings = r.bindings.values().iterator();
	while (bindings.hasNext()) {
		IntentBindRecord i = bindings.next();
		//调用requestServiceBindingLocked()函数绑定前Service
		if (!requestServiceBindingLocked(r, i, false)) {
			break;
		}
	}
}

ServiceRecord的成员变量bindings中保存了需要绑定当前Service的IntentBindRecord对象,在该函数中就是遍历bindings列表,然后调用requestServiceBindingLocked()函数来与当前Service绑定

frameworks/base/services/java/com/android/server/am/ActivityManagerService.java
private final boolean requestServiceBindingLocked(ServiceRecord r,
		IntentBindRecord i, boolean rebind) {
	if (r.app == null || r.app.thread == null) {
		// If service is not currently running, can't yet bind.
		return false;
	}
	if ((!i.requested || rebind) && i.apps.size() > 0) {
		try {
			bumpServiceExecutingLocked(r, "bind");
			//请求绑定服务
			r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind);
			if (!rebind) {
				i.requested = true;
			}
			i.hasBound = true;
			i.doRebind = false;
		} catch (RemoteException e) {
			if (DEBUG_SERVICE) Slog.v(TAG, "Crashed while binding " + r);
			return false;
		}
	}
	return true;
}

ActivityManagerService通过跨进程调用Service运行进程ApplicationThread的scheduleBindService函数来绑定服务

frameworks\base\core\java\android\app\ActivityThread.$ApplicationThread
public final void scheduleBindService(IBinder token, Intent intent,
		boolean rebind) {
	BindServiceData s = new BindServiceData();
	s.token = token;
	s.intent = intent;
	s.rebind = rebind;
	if (DEBUG_SERVICE)
		Slog.v(TAG, "scheduleBindService token=" + token + " intent=" + intent + " uid="
				+ Binder.getCallingUid() + " pid=" + Binder.getCallingPid());
	queueOrSendMessage(H.BIND_SERVICE, s);
}

将ActivityManagerService的RPC调用转换为本地异步调用

frameworks\base\core\java\android\app\ActivityThread.$H
public void handleMessage(Message msg) {
	if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
	switch (msg.what) {
	case BIND_SERVICE:
		Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceBind");
		handleBindService((BindServiceData)msg.obj);
		Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
		break;
	}
}
这里又将Service的创建工作交给H的外部类ActivityThread的handleBindService()函数来完成。
frameworks\base\core\java\android\app\ActivityThread.java
private void handleBindService(BindServiceData data) {
	//data.token为Service在AMS中的ServiceRecord
	Service s = mServices.get(data.token);
	if (DEBUG_SERVICE)
		Slog.v(TAG, "handleBindService s=" + s + " rebind=" + data.rebind);
	if (s != null) {
		try {
			data.intent.setExtrasClassLoader(s.getClassLoader());
			try {
				//是否重新绑定
				if (!data.rebind) {
					//回调Service的onBind函数
					IBinder binder = s.onBind(data.intent);
					//AMS回调ServiceConnection的connected函数
					ActivityManagerNative.getDefault().publishService(
							data.token, data.intent, binder);
				} else {
					//回调Service的onRebind函数
					s.onRebind(data.intent);
					ActivityManagerNative.getDefault().serviceDoneExecuting(
							data.token, 0, 0, 0);
				}
				ensureJitEnabled();
			} catch (RemoteException ex) {
			}
		} catch (Exception e) {
			if (!mInstrumentation.onException(s, e)) {
				throw new RuntimeException(
						"Unable to bind to service " + s
						+ " with " + data.intent + ": " + e.toString(), e);
			}
		}
	}
}

在该函数里,Service运行的应用程序进程调用Service的onBind函数。

frameworks/base/services/java/com/android/server/am/ActivityManagerService.java
public void publishService(IBinder token, Intent intent, IBinder service) {
	// Refuse possible leaked file descriptors
	if (intent != null && intent.hasFileDescriptors() == true) {
		throw new IllegalArgumentException("File descriptors passed in Intent");
	}
	synchronized(this) {
		if (!(token instanceof ServiceRecord)) {
			throw new IllegalArgumentException("Invalid service token");
		}
		ServiceRecord r = (ServiceRecord)token;

		final long origId = Binder.clearCallingIdentity();

		if (DEBUG_SERVICE) Slog.v(TAG, "PUBLISHING " + r
				+ " " + intent + ": " + service);
		if (r != null) {
			Intent.FilterComparison filter
					= new Intent.FilterComparison(intent);
			IntentBindRecord b = r.bindings.get(filter);
			if (b != null && !b.received) {
				b.binder = service;
				b.requested = true;
				b.received = true;
				if (r.connections.size() > 0) {
					Iterator<ArrayList<ConnectionRecord>> it
							= r.connections.values().iterator();
					while (it.hasNext()) {
						ArrayList<ConnectionRecord> clist = it.next();
						for (int i=0; i<clist.size(); i++) {
							ConnectionRecord c = clist.get(i);
							if (!filter.equals(c.binding.intent.intent)) {
								if (DEBUG_SERVICE) Slog.v(
										TAG, "Not publishing to: " + c);
								if (DEBUG_SERVICE) Slog.v(
										TAG, "Bound intent: " + c.binding.intent.intent);
								if (DEBUG_SERVICE) Slog.v(
										TAG, "Published intent: " + intent);
								continue;
							}
							if (DEBUG_SERVICE) Slog.v(TAG, "Publishing to: " + c);
							try {
								c.conn.connected(r.name, service);
							} catch (Exception e) {
								Slog.w(TAG, "Failure sending service " + r.name +
									  " to connection " + c.conn.asBinder() +
									  " (in " + c.binding.client.processName + ")", e);
							}
						}
					}
				}
			}
			serviceDoneExecutingLocked(r, mStoppingServices.contains(r));
			Binder.restoreCallingIdentity(origId);
		}
	}
}

Service启动过程

frameworks/base/services/java/com/android/server/am/ActivityManagerService.java

private final void sendServiceArgsLocked(ServiceRecord r,
		boolean oomAdjusted) {
	final int N = r.pendingStarts.size();
	if (N == 0) {
		return;
	}
	//遍历Service启动参数列表
	while (r.pendingStarts.size() > 0) {
		try {
			//对参数列表中的每一项StartItem都启动一次Service
			ServiceRecord.StartItem si = r.pendingStarts.remove(0);
			if (DEBUG_SERVICE) Slog.v(TAG, "Sending arguments to: "
					+ r + " " + r.intent + " args=" + si.intent);
			if (si.intent == null && N > 1) {
				// If somehow we got a dummy null intent in the middle,
				// then skip it.  DO NOT skip a null intent when it is
				// the only one in the list -- this is to support the
				// onStartCommand(null) case.
				continue;
			}
			//设置投递时间
			si.deliveredTime = SystemClock.uptimeMillis();
			//将已投递参数项保存到deliveredStarts列表中
			r.deliveredStarts.add(si);
			si.deliveryCount++;
			if (si.neededGrants != null) {
				grantUriPermissionUncheckedFromIntentLocked(si.neededGrants,
						si.getUriPermissionsLocked());
			}
			bumpServiceExecutingLocked(r, "start");
			if (!oomAdjusted) {
				oomAdjusted = true;
				updateOomAdjLocked(r.app);
			}
			int flags = 0;
			if (si.deliveryCount > 1) {
				flags |= Service.START_FLAG_RETRY;
			}
			if (si.doneExecutingCount > 0) {
				flags |= Service.START_FLAG_REDELIVERY;
			}
			//RPC调用Service运行进程的scheduleServiceArgs函数启动Service服务
			r.app.thread.scheduleServiceArgs(r, si.taskRemoved, si.id, flags, si.intent);
		} catch (RemoteException e) {
			// Remote process gone...  we'll let the normal cleanup take
			// care of this.
			if (DEBUG_SERVICE) Slog.v(TAG, "Crashed while scheduling start: " + r);
			break;
		} catch (Exception e) {
			Slog.w(TAG, "Unexpected exception", e);
			break;
		}
	}
}

和上面Service创建及绑定过程类似,这里仍然是通过Binder跨进程函数调用方式调用Service运行进程中的ApplicationThread Binder本地对象的scheduleServiceArgs()函数来启动Service

frameworks\base\core\java\android\app\ActivityThread.$ApplicationThread
public final void scheduleServiceArgs(IBinder token, boolean taskRemoved, int startId,
	int flags ,Intent args) {
	ServiceArgsData s = new ServiceArgsData();
	s.token = token;
	s.taskRemoved = taskRemoved;
	s.startId = startId;
	s.flags = flags;
	s.args = args;
	queueOrSendMessage(H.SERVICE_ARGS, s);
}

将RPC函数调用转换为应用程序进程中的异步调用

frameworks\base\core\java\android\app\ActivityThread.$H
public void handleMessage(Message msg) {
	if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
	switch (msg.what) {
	case SERVICE_ARGS:
		Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceStart");
		handleServiceArgs((ServiceArgsData)msg.obj);
		Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
		break;
	}
}

该函数直接调用ActivityThread类的handleServiceArgs()函数来启动Service

frameworks\base\core\java\android\app\ActivityThread.java
private void handleServiceArgs(ServiceArgsData data) {
	Service s = mServices.get(data.token);
	if (s != null) {
		try {
			if (data.args != null) {
				data.args.setExtrasClassLoader(s.getClassLoader());
			}
			int res;
			if (!data.taskRemoved) {
				//回调Service的onStartCommand函数
				res = s.onStartCommand(data.args, data.flags, data.startId);
			} else {
				s.onTaskRemoved(data.args);
				res = Service.START_TASK_REMOVED_COMPLETE;
			}
			QueuedWork.waitToFinish();
			try {
				//通知ActivityManagerService服务Service启动完成
				ActivityManagerNative.getDefault().serviceDoneExecuting(
						data.token, 1, data.startId, res);
			} catch (RemoteException e) {
				// nothing to do.
			}
			ensureJitEnabled();
		} catch (Exception e) {
			if (!mInstrumentation.onException(s, e)) {
				throw new RuntimeException(
						"Unable to start service " + s
						+ " with " + data.args + ": " + e.toString(), e);
			}
		}
	}
}

本文完整介绍了Service的创建启动过程,无论是Service的创建还是启动,Android应用程序进程自身都无法完成,必须通过ActivityManagerService服务调度实现,只有在ActivityManagerService服务端备案后,由ActivityManagerService服务通知应用程序进程来创建并启动Service。

抱歉!评论已关闭.