本文主要是介绍Android服务启动之StartService源码分析,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
在编写Android应用程序时,我们一般将比较耗时的操作放在一个独立的进程来处理,这样主进程仍然可以流畅地响应界面事件,提高用户体验。Android系统为我们提供了一个Service类,我们可以实现一个以Service为基类的服务子类,在里面实现自己的计算型逻辑,然后在主进程通过startService函数来启动这个服务。在本文中,将详细分析应用程序进程是如何通过startService函数来启动自定义服务的。
请求启动Service
frameworks\base\core\java\android\content\Context.java
- public abstract ComponentName startService(Intent service);
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);
- }
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;
- }
- }
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;
- }
- }
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;
- }
- }
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;
- }
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;
- }
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);
- }
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创建过程
- 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);
- }
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()函数中,完成对该消息的处理: - 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;
- }
- }
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()函数来完成。 - 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);
- }
- }
- }
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绑定过程
- 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;
- }
- }
- }
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绑定 - 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;
- }
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函数来绑定服务 - 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);
- }
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调用转换为本地异步调用 - 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;
- }
- }
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;
}
}
- 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);
- }
- }
- }
- }
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函数。 - 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);
- }
- }
- }
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启动过程
- 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;
- }
- }
- }
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 - 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);
- }
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函数调用转换为应用程序进程中的异步调用 - 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;
- }
- }
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 - 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);
- }
- }
- }
- }
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。
这篇关于Android服务启动之StartService源码分析的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!