Android服务启动之StartService源码分析

浏览:
字体:
发布时间:2013-12-12 14:50:56
来源:

在编写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该函数通过一系列处理后,为当前启动的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 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> it							= r.connections.values().iterator();					while (it.hasNext()) {						ArrayList clist = it.next();						for (int i=0; i/

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()函数来启动Serviceframeworks/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()函数来启动Serviceframeworks/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。


>更多相关文章
24小时热门资讯
24小时回复排行
资讯 | QQ | 安全 | 编程 | 数据库 | 系统 | 网络 | 考试 | 站长 | 关于东联 | 安全雇佣 | 搞笑视频大全 | 微信学院 | 视频课程 |
关于我们 | 联系我们 | 广告服务 | 免责申明 | 作品发布 | 网站地图 | 官方微博 | 技术培训
Copyright © 2007 - 2024 Vm888.Com. All Rights Reserved
粤公网安备 44060402001498号 粤ICP备19097316号 请遵循相关法律法规
');})();