Service计算型组件,用于后台执行一系列计算任务。
启动Service可以在当前进程里面启动,也可以在在新进程里面启动,启动服务的方式有两种startService和bindService。
下面分析新进程里startService的这种情况,对应的时序图。主要生命周期为onCreate,onStartCommand,onDestroy:
startService的入口在ContextImpl里:
@Override
public ComponentName startService(Intent service) {
warnIfCallingFromSystemProcess();//系统启动打印日志
return startServiceCommon(service, mUser);
}
startServiceCommon里面调用validateServiceIntent方法验证我们的Intent,在Android 5.0以后就不能使用隐式意图来启动Service,如果某些情况下还是需要隐式意图,通过给Intent设置Component或者Package就可以避免抛异常。
private ComponentName startServiceCommon(Intent service, UserHandle user) {
try {
validateServiceIntent(service);//验证Intent
ComponentName cn = ActivityManagerNative.getDefault().startService(
mMainThread.getApplicationThread(), service,
service.resolveTypeIfNeeded(getContentResolver()), user.getIdentifier());
//...
return cn;
} catch (RemoteException e) {
return null;
}
}
private void validateServiceIntent(Intent service) {
if (service.getComponent() == null && service.getPackage() == null) {
if (getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.LOLLIPOP) {
IllegalArgumentException ex = new IllegalArgumentException(
"Service Intent must be explicit: " + service);
throw ex;
}
//...
}
}
之后通过ActivityManagerNative.getDefault()获得ActivityManagerProxy,通过ActivityManagerProxy向ActivityManagerService发起IPC调用,第一个参数的ApplicationThread是ActivityThread里面的成员变量。
//ActivityManagerProxy.java:
public ComponentName startService(IApplicationThread caller, Intent service,
String resolvedType, int userId) throws RemoteException
{
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
data.writeInterfaceToken(IActivityManager.descriptor);
data.writeStrongBinder(caller != null ? caller.asBinder() : null);
service.writeToParcel(data, 0);
data.writeString(resolvedType);
data.writeInt(userId);
mRemote.transact(START_SERVICE_TRANSACTION, data, reply, 0);
reply.readException();
ComponentName res = ComponentName.readFromParcel(reply);
data.recycle();
reply.recycle();
return res;
}
然后进入到ActivityManagerService里:
//ActivityManagerService.java
final ActiveServices mServices;
@Override
public ComponentName startService(IApplicationThread caller, Intent service,
String resolvedType, int userId) {
//...
synchronized(this) {
final int callingPid = Binder.getCallingPid();
final int callingUid = Binder.getCallingUid();
final long origId = Binder.clearCallingIdentity();
ComponentName res = mServices.startServiceLocked(caller, service,
resolvedType, callingPid, callingUid, userId);
Binder.restoreCallingIdentity(origId);
return res;
}
}
ActiveServices用来管理Service,然后调用startServiceLocked:
//ActiveServices.java
ComponentName startServiceLocked(IApplicationThread caller,
Intent service, String resolvedType,
int callingPid, int callingUid, int userId) {
final boolean callerFg;
if (caller != null) {//不为空
final ProcessRecord callerApp = mAm.getRecordForAppLocked(caller);
if (callerApp == null) {
throw new SecurityException(
"Unable to find app for caller " + caller
- " (pid=" + Binder.getCallingPid()
- ") when starting service " + service);
}
callerFg = callerApp.setSchedGroup != Process.THREAD_GROUP_BG_NONINTERACTIVE;//false
} else {
callerFg = true;
}
//ServiceRecord表示一个Service实例
//PackageManagerService解析出Intent得到要启动的ServiceRecord
ServiceLookupResult res =
retrieveServiceLocked(service, resolvedType,
callingPid, callingUid, userId, true, callerFg);
//...
ServiceRecord r = res.record;
//...
r.lastActivity = SystemClock.uptimeMillis();
r.startRequested = true;
r.delayedStop = false;
//ServiceRecord.StartItem表示startService的一次调用,并生成startId,stopService使用
r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
service, neededGrants));
final ServiceMap smap = getServiceMap(r.userId);
boolean addToStarting = false;
//ProcessRecord表示一个正在运行的进程实例
//新进程里面的ProcessRecord为空
if (!callerFg && r.app == null && mAm.mStartedUsers.get(r.userId) != null) {
ProcessRecord proc = mAm.getProcessRecordLocked(r.processName, r.appInfo.uid, false);
if (proc == null || proc.curProcState > ActivityManager.PROCESS_STATE_RECEIVER) {
if (r.delayed) {
return r.name;
}
//超过单用户最大启动Service的数量,延迟启动
if (smap.mStartingBackground.size() >= mMaxStartingBackground) {
smap.mDelayedStartList.add(r);
r.delayed = true;
return r.name;
}
addToStarting = true;
} else if (proc.curProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
addToStarting = true;
}
//...
return startServiceInnerLocked(smap, service, r, callerFg, addToStarting);
}
ServiceRecord表示一个Service实例,ServiceRecord.StartItem表示startService的一次调用,并生成startId,stopService使用,ServiceMap用来映射userId与之对应的Service,之后调用startServiceInnerLocked,ServiceRecord.startRequested为true,callerFg为false(这里假设是从Activity里面启动),addToStarting为true:
ComponentName startServiceInnerLocked(ServiceMap smap, Intent service,
ServiceRecord r, boolean callerFg, boolean addToStarting) {
//...
r.callStart = false;
String error = bringUpServiceLocked(r, service.getFlags(), callerFg, false);
//...
return r.name;
}
之后调用bringUpServiceLocked,callerFg为false:
//execInFg为false,whileRestarting为false
private final String bringUpServiceLocked(ServiceRecord r,
int intentFlags, boolean execInFg, boolean whileRestarting) {
//如果进程已经存在的情况下就不是处理下面的流程,直接处理onStart的流程
if (r.app != null && r.app.thread != null) {
sendServiceArgsLocked(r, execInFg, false);
return null;
}
//处于restart的状态(在onStartCommand里面处理了服务被杀之后的行为)也不会处理
if (!whileRestarting && r.restartDelay > 0) {
return null;
}
if (mRestartingServices.remove(r)) {
clearRestartingIfNeededLocked(r);
}
if (r.delayed) {
getServiceMap(r.userId).mDelayedStartList.remove(r);
r.delayed = false;
}
//...
final boolean isolated = (r.serviceInfo.flags&ServiceInfo.FLAG_ISOLATED_PROCESS) != 0;
final String procName = r.processName;
ProcessRecord app;
//独立的进程运行isolated为true
if (!isolated) {
app = mAm.getProcessRecordLocked(procName, r.appInfo.uid, false);
if (app != null && app.thread != null) {
try {
app.addPackage(r.appInfo.packageName, r.appInfo.versionCode, mAm.mProcessStats);
//直接启动服务,不用开启新的进程
realStartServiceLocked(r, app, execInFg);
return null;
} catch (RemoteException e) {
Slog.w(TAG, "Exception when starting service " + r.shortName, e);
}
}
} else {
app = r.isolatedProc;
}
if (app == null) {
//开启新的进程
if ((app=mAm.startProcessLocked(procName, r.appInfo, true, intentFlags,
"service", r.name, false, isolated, false)) == null) {
bringDownServiceLocked(r);
return msg;
}
if (isolated) {
r.isolatedProc = app;
}
}
//将ServiceRecord加入即将启动mPendingServices列表里,后面进程启动成功后在启动Service
if (!mPendingServices.contains(r)) {
mPendingServices.add(r);
}
//...
return null;
}
如果进程已经存在的情况下就不是处理下面的流程,直接调用realStartServiceLocked处理onStart的流程。
ActivityManagerService.startProcessLocked开启进程,procName为AndroidManifest中Service标签了process指定的进程名,默认是包名。
//ActivityManagerService.java
//knownToBeDead为true,hostingType为"service",allowWhileBooting为false
final ProcessRecord startProcessLocked(String processName,
ApplicationInfo info, boolean knownToBeDead, int intentFlags,
String hostingType, ComponentName hostingName, boolean allowWhileBooting,
boolean isolated, boolean keepIfLarge) {
return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
null /* crashHandler */);
}
接着调用startProcessLocked:
//ActivityManagerService.java
final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
ProcessRecord app;
if (!isolated) {
app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
} else {
// If this is an isolated process, it can't re-use an existing process.
app = null;
}
//...
String hostingNameStr = hostingName != null
? hostingName.flattenToShortString() : null;
//...
if (app == null) {
//构建一个新的的ProcessRecord
app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
app.crashHandler = crashHandler;
mProcessNames.put(processName, app.uid, app);
if (isolated) {
mIsolatedProcesses.put(app.uid, app);
}
}
//...
startProcessLocked(
app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
return (app.pid != 0) ? app : null;
}
处理进程已经存在的情况,构建新的ProcessRecord,startProcessLocked开启进程:
private final void startProcessLocked(ProcessRecord app, String hostingType,
String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
//...
try {
int uid = app.uid;
int[] gids = null;
int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
if (!app.isolated) {
//...
}
int debugFlags = 0;
//...
boolean isActivityProcess = (entryPoint == null);
if (entryPoint == null) entryPoint = "android.app.ActivityThread";
Process.ProcessStartResult startResult = Process.start(entryPoint,
app.processName, uid, uid, gids, debugFlags, mountExternal,
app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
app.info.dataDir, entryPointArgs);
//...
}
调用Process.start开启一个新的进程,新进程的入口点就是android.app.ActivityThread,执行里面的main方法。
public final class ActivityThread {
final ApplicationThread mAppThread = new ApplicationThread();
public static void main(String[] args) {
//...
Looper.prepareMainLooper();
ActivityThread thread = new ActivityThread();
thread.attach(false);
if (sMainThreadHandler == null) {
sMainThreadHandler = thread.getHandler();
}
Looper.loop();
throw new RuntimeException("Main thread loop unexpectedly exited");
}
private void attach(boolean system) {
//...
if (!system) {
//...
final IActivityManager mgr = ActivityManagerNative.getDefault();
try {
mgr.attachApplication(mAppThread);
} catch (RemoteException ex) {
// Ignore
}
//...
}
}
}
准备主线程的Looper,调用attachApplication通知ActiviyManangerService主线程准备完毕,然后loop开始消息循环。
ActivityManagerProxy通过IPC向ActivityManagerService调用attachApplication,并传递mAppThread给ActivityManagerService,mAppThread是一个Binder对象,用于ActivityManagerService向我们发起调用。注意从这里开始已经是在新进程里面执行了。
class ActivityManagerProxy implements IActivityManager{
public void attachApplication(IApplicationThread app) throws RemoteException
{
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
data.writeInterfaceToken(IActivityManager.descriptor);
data.writeStrongBinder(app.asBinder());
mRemote.transact(ATTACH_APPLICATION_TRANSACTION, data, reply, 0);
reply.readException();
data.recycle();
reply.recycle();
}
}
遂进入到ActivityManagerService:
@Override
public final void attachApplication(IApplicationThread thread) {
synchronized (this) {
int callingPid = Binder.getCallingPid();
final long origId = Binder.clearCallingIdentity();
attachApplicationLocked(thread, callingPid);
Binder.restoreCallingIdentity(origId);
}
}
private final boolean attachApplicationLocked(IApplicationThread thread,
int pid) {
ProcessRecord app;
//MY_PID是ActivityManagerService所在进程的pid
if (pid != MY_PID && pid >= 0) {
synchronized (mPidsSelfLocked) {
app = mPidsSelfLocked.get(pid);
}
} else {
app = null;
}
//No pending application record for pid,drop this process
if (app == null) {
//...
return false;
}
//...
final String processName = app.processName;
//...
app.makeActive(thread, mProcessStats);
app.curAdj = app.setAdj = -100;
app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
app.forcingToForeground = null;
updateProcessForegroundLocked(app, false, false);
app.hasShownUi = false;
app.debugging = false;
app.cached = false;
app.killedByAm = false;
//...
try{
thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
isRestrictedBackupMode || !normalMode, app.persistent,
new Configuration(mConfiguration), app.compat,
getCommonServicesLocked(app.isolated),
mCoreSettingsObserver.getCoreSettingsLocked());
//用lru更新AMS维护的进程列表
updateLruProcessLocked(app, false, null);
app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
} catch (Exception e) {
//...
return false;
}
boolean badApp = false;
//...
// Find any services that should be running in this process...
if (!badApp) {
try {
didSomething |= mServices.attachApplicationLocked(app, processName);
} catch (Exception e) {
Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
badApp = true;
}
}
//...
return true;
}
使用ApplicationThread发起IPC调用bindApplication:
public final void bindApplication(String processName, ApplicationInfo appInfo,
List<ProviderInfo> providers, ComponentName instrumentationName,
ProfilerInfo profilerInfo, Bundle instrumentationArgs,
IInstrumentationWatcher instrumentationWatcher,
IUiAutomationConnection instrumentationUiConnection, int debugMode,
boolean enableOpenGlTrace, boolean isRestrictedBackupMode, boolean persistent,
Configuration config, CompatibilityInfo compatInfo, Map<String, IBinder> services,
Bundle coreSettings) {
//... init
IPackageManager pm = getPackageManager();
android.content.pm.PackageInfo pi = null;
try {
pi = pm.getPackageInfo(appInfo.packageName, 0, UserHandle.myUserId());
} catch (RemoteException e) {
}
if (pi != null) {
//处理sharedUid的情况
//...
}
AppBindData data = new AppBindData();
data.processName = processName;
data.appInfo = appInfo;
data.providers = providers;
data.instrumentationName = instrumentationName;
data.instrumentationArgs = instrumentationArgs;
data.instrumentationWatcher = instrumentationWatcher;
data.instrumentationUiAutomationConnection = instrumentationUiConnection;
data.debugMode = debugMode;
data.enableOpenGlTrace = enableOpenGlTrace;
data.restrictedBackupMode = isRestrictedBackupMode;
data.persistent = persistent;
data.config = config;
data.compatInfo = compatInfo;
data.initProfilerInfo = profilerInfo;
sendMessage(H.BIND_APPLICATION, data);
}
private void sendMessage(int what, Object obj) {
sendMessage(what, obj, 0, 0, false);
}
final H mH = new H();
private void sendMessage(int what, Object obj, int arg1, int arg2, boolean async) {
Message msg = Message.obtain();
msg.what = what;
msg.obj = obj;
msg.arg1 = arg1;
msg.arg2 = arg2;
if (async) {
msg.setAsynchronous(true);
}
mH.sendMessage(msg);
}
主线程的Looper前面已经在ActivityThread主线程里面初始化了,然后然后向Handler发消息实现进程切换(因为bindApplication是在客户端Binder线程池里面调用的)。
private class H extends Handler {
public void handleMessage(Message msg) {
//...
case BIND_APPLICATION:
AppBindData data = (AppBindData)msg.obj;
handleBindApplication(data);
break;
}
}
接着调用ActivityThread的handleBindApplication,主要是然客户端初始化应用程序的一些状态比如时区地域,Instrumentation,LoadedApk等等。
private void handleBindApplication(AppBindData data) {
mBoundApplication = data;
mConfiguration = new Configuration(data.config);
mCompatConfiguration = new Configuration(data.config);
//...
TimeZone.setDefault(null);
//...
Locale.setDefault(data.config.locale);
//...
}
再回到ActivityManagerService中的attachApplicationLocked,接着调用ActivieServices的attachApplicationLocked通知客户端启动Service:
if (!badApp) {
try {
didSomething |= mServices.attachApplicationLocked(app, processName);
} catch (Exception e) {
Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
badApp = true;
}
}
mPendingServices就是前面加入列表的ServiceRecord,过滤要启动的ServiceRecord,调用
realStartServiceLocked:
boolean attachApplicationLocked(ProcessRecord proc, String processName)
throws RemoteException {
boolean didSomething = false;
// Collect any services that are waiting for this process to come up.
if (mPendingServices.size() > 0) {
ServiceRecord sr = null;
try {
for (int i=0; i<mPendingServices.size(); i++) {
sr = mPendingServices.get(i);
//过滤我们客户端当前的进程
if (proc != sr.isolatedProc && (proc.uid != sr.appInfo.uid
|| !processName.equals(sr.processName))) {
continue;
}
mPendingServices.remove(i);
i--;
proc.addPackage(sr.appInfo.packageName, sr.appInfo.versionCode,
mAm.mProcessStats);
realStartServiceLocked(sr, proc, sr.createdFromFg);
didSomething = true;
}
} catch (RemoteException e) {
Slog.w(TAG, "Exception in new application when starting service "
- sr.shortName, e);
throw e;
}
}
if (mRestartingServices.size() > 0) {
//处理restart的状态
//...
}
return didSomething;
}
调用ApplicationThread的scheduleCreateService然客户端创建服务,pendingStarts在放入要执行start操作的列表里面,在执行sendServiceArgsLocked告诉客户端执行onStart:
private final void realStartServiceLocked(ServiceRecord r,
ProcessRecord app, boolean execInFg) throws RemoteException {
//..
r.app = app;
r.restartTime = r.lastActivity = SystemClock.uptimeMillis();
app.services.add(r);
//将Service加入到正在执行的executingServices(ProcessRecord)列表里
bumpServiceExecutingLocked(r, execInFg, "create");
mAm.updateLruProcessLocked(app, false, null);
mAm.updateOomAdjLocked();
boolean created = false;
try {
//...
app.thread.scheduleCreateService(r, r.serviceInfo,
mAm.compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo),
app.repProcState);
//前台进程显示Notification
r.postNotification();
created = true;
} catch (DeadObjectException e) {
//...
}
// 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));
}
sendServiceArgsLocked(r, execInFg, true);
//...
}
先看ApplicationThread的scheduleCreateService,这里对应的token就是ActivityManagerService创建的ServiceRecord,ServiceInfo是ActivityManagerService为我们解析AndroidManifest的Service标签:
//ApplicationThread.java
public final void scheduleCreateService(IBinder token,
ServiceInfo info, CompatibilityInfo compatInfo, int processState) {
updateProcessState(processState, false);
CreateServiceData s = new CreateServiceData();
s.token = token;
s.info = info;
s.compatInfo = compatInfo;
sendMessage(H.CREATE_SERVICE, s);
}
同样是向Handler发送消息实现进程切换:
private class H extends Handler {
public void handleMessage(Message msg) {
//...
case CREATE_SERVICE:
handleCreateService((CreateServiceData)msg.obj);
break;
//...
}
}
执行ActivityThread的handleCreateService,实现创建服务并执行onCreate,调用ActivityManagerService的serviceDoneExecuting,onCreate更新下Service的一些状态:
private void handleCreateService(CreateServiceData data) {
//...
//前面已经初始化好的LoadedApk
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) {
//...
}
try {
ContextImpl context = ContextImpl.createAppContext(this, packageInfo);
context.setOuterContext(service);
//如果新进程没有创建Application则创建
Application app = packageInfo.makeApplication(false, mInstrumentation);
//初始化Service
service.attach(context, this, data.info.name, data.token, app,
ActivityManagerNative.getDefault());
service.onCreate();
mServices.put(data.token, service);
try {
ActivityManagerNative.getDefault().serviceDoneExecuting(
data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);
} catch (RemoteException e) {
// nothing to do.
}
} catch (Exception e) {
//...
}
}
再回到上面的ActivieServices的sendServiceArgsLocked告诉客户端要执行onStartCommand,将要执行的onStart的参数(例如startId)传回客户端:
private final void sendServiceArgsLocked(ServiceRecord r, boolean execInFg,
boolean oomAdjusted) {
//...
while (r.pendingStarts.size() > 0) {
try {
ServiceRecord.StartItem si = r.pendingStarts.remove(0);
//...
si.deliveredTime = SystemClock.uptimeMillis();
r.deliveredStarts.add(si);
si.deliveryCount++;
//更新正在执行的状态
bumpServiceExecutingLocked(r, execInFg, "start");
int flags = 0;
if (si.deliveryCount > 1) {
flags |= Service.START_FLAG_RETRY;
}
if (si.doneExecutingCount > 0) {
flags |= Service.START_FLAG_REDELIVERY;
}
r.app.thread.scheduleServiceArgs(r, si.taskRemoved, si.id, flags, si.intent);
} catch (RemoteException e) {
//...
}
}
}
接着执行ActivityThread里的scheduleServiceArgs:
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;
sendMessage(H.SERVICE_ARGS, s);
}
同样发送消息给主线程执行handleServiceArgs,mServices为客户端维护的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());
data.args.prepareToEnterProcess();
}
int res;
if (!data.taskRemoved) {
res = s.onStartCommand(data.args, data.flags, data.startId);
} else {
s.onTaskRemoved(data.args);
res = Service.START_TASK_REMOVED_COMPLETE;
}
//...
try {
ActivityManagerNative.getDefault().serviceDoneExecuting(
data.token, SERVICE_DONE_EXECUTING_START, data.startId, res);
} catch (RemoteException e) {
// nothing to do.
}
ensureJitEnabled();
} catch (Exception e) {
///...
}
}
}
onStartCommand执行完后会返回一个参数,用于控制Service的一些行为,例如进程被杀死之后Service的行为。
随后调用serviceDoneExecuting告诉ActivityManagerService,onStart已经执行完了,ActivityManagerService再更新一些状态。
就这样Service就运行起来了。
停止服务有两种方式,一种是在程序外面通过ContextImpl的接口,stopService来停止,另一种是在Service里面调用stop来停止。
通过ContextImpl接口:
class ContextImpl extends Context {
@Override
public boolean stopService(Intent service) {
warnIfCallingFromSystemProcess();
return stopServiceCommon(service, mUser);
}
private boolean stopServiceCommon(Intent service, UserHandle user) {
try {
validateServiceIntent(service);//系统进程调用打印日志
service.prepareToLeaveProcess();
int res = ActivityManagerNative.getDefault().stopService(
mMainThread.getApplicationThread(), service,
service.resolveTypeIfNeeded(getContentResolver()), user.getIdentifier());
//...
return res != 0;
} catch (RemoteException e) {
return false;
}
}
}
接着向ActivityManagerService发起IPC调用,进入ActivityManagerService里面的stopService:
@Override
public int stopService(IApplicationThread caller, Intent service,
String resolvedType, int userId) {
//...
synchronized(this) {
return mServices.stopServiceLocked(caller, service, resolvedType, userId);
}
}
接着调用ActivieServices的stopServiceLocked方法:
int stopServiceLocked(IApplicationThread caller, Intent service,
String resolvedType, int userId) {
//...
//找到正在运行的ServiceRecord
// If this service is active, make sure it is stopped.
ServiceLookupResult r = retrieveServiceLocked(service, resolvedType,
Binder.getCallingPid(), Binder.getCallingUid(), userId, false, false);
if (r != null) {
if (r.record != null) {
final long origId = Binder.clearCallingIdentity();
try {
stopServiceLocked(r.record);
} finally {
Binder.restoreCallingIdentity(origId);
}
return 1;
}
return -1;
}
return 0;
}
找到正在运行的ServiceRecord,调用stopServiceLocked进行下一步操作:
private void stopServiceLocked(ServiceRecord service) {
//...
service.startRequested = false;
service.callStart = false;
bringDownServiceIfNeededLocked(service, false, false);
}
private final void bringDownServiceIfNeededLocked(ServiceRecord r, boolean knowConn,
boolean hasConn) {
//如果判断服务处于被绑定的状态,则不会停止服务
if (isServiceNeeded(r, knowConn, hasConn)) {
return;
}
// Are we in the process of launching?
if (mPendingServices.contains(r)) {
return;
}
bringDownServiceLocked(r);
}
如果服务有绑定的客户端,或者即将启动的服务里面包含了要停止的服务,则直接返回,否则调用bringDownServiceLocked进行下一步处理:
private final void bringDownServiceLocked(ServiceRecord r) {
// Report to all of the connections that the service is no longer
// available.
for (int conni=r.connections.size()-1; conni>=0; conni--) {
//...
}
// Tell the service that it has been unbound.
if (r.app != null && r.app.thread != null) {
for (int i=r.bindings.size()-1; i>=0; i--) {
//...
r.app.thread.scheduleUnbindService(r,
ibr.intent.getIntent());
//...
}
}
r.destroyTime = SystemClock.uptimeMillis();
final ServiceMap smap = getServiceMap(r.userId);
smap.mServicesByName.remove(r.name);
smap.mServicesByIntent.remove(r.intent);
r.totalRestartCount = 0;
unscheduleServiceRestartLocked(r, 0, true);
// Also make sure it is not on the pending list.
for (int i=mPendingServices.size()-1; i>=0; i--) {
if (mPendingServices.get(i) == r) {
mPendingServices.remove(i);
}
}
r.cancelNotification();
r.isForeground = false;
r.foregroundId = 0;
r.foregroundNoti = null;
// Clear start entries.
r.clearDeliveredStartsLocked();
r.pendingStarts.clear();
if (r.app != null) {
r.app.services.remove(r);
if (r.app.thread != null) {
updateServiceForegroundLocked(r.app, false);
try {
bumpServiceExecutingLocked(r, false, "destroy");
mDestroyingServices.add(r);
r.destroying = true;
r.app.thread.scheduleStopService(r);
} catch (Exception e) {
//...
}
}
}
//...
}
由于没有绑定服务,则不会执行服务解绑scheduleUnbindService的操作。这一步主要就是更新ServiceRecord的一些状态,将ServiceRecord加入mDestroyingServices里后面用到,然后调用客户端的ApplicationThread#scheduleStopService,这里的token为对应的ServiceRecord:
private class ApplicationThread extends ApplicationThreadNative {
public final void scheduleStopService(IBinder token) {
sendMessage(H.STOP_SERVICE, token);
}
}
同样向Handler发送消息切换进程执行AcitivtyThread#handleStopService:
private void handleStopService(IBinder token) {
Service s = mServices.remove(token);
if (s != null) {
try {
s.onDestroy();
Context context = s.getBaseContext();
if (context instanceof ContextImpl) {
final String who = s.getClassName();
//清除掉使用这个Context创建的资源,比如注册的广播,绑定的服务(直接抛异常)
((ContextImpl) context).scheduleFinalCleanup(who, "Service");
}
try {
ActivityManagerNative.getDefault().serviceDoneExecuting(
token, SERVICE_DONE_EXECUTING_STOP, 0, 0);
} catch (RemoteException e) {
//...
}
} catch (Exception e) {
//...
}
}
//...
}
首先从客户端保存的mServices里面取出对应的Service实例,调用onDestroy,之后调用scheduleFinalCleanup清除掉使用这个Context创建的资源,比如注册的广播,绑定的服务。之后调用ActivityManagerProxy#serviceDoneExecuting,告诉ActivityManagerService已经结束执行完onDestroy。然后就进入到ActivityManagerService#serviceDoneExecuting:
public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
synchronized(this) {
//...验证token是否是ServiceRecord
mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
}
}
接着执行ActiveServices#serviceDoneExecutingLocked进行下一步操作:
void serviceDoneExecutingLocked(ServiceRecord r, int type, int startId, int res) {
boolean inDestroying = mDestroyingServices.contains(r);
if (r != null) {
if (type == ActivityThread.SERVICE_DONE_EXECUTING_START) {
//...
} else if (type == ActivityThread.SERVICE_DONE_EXECUTING_STOP) {
if (!inDestroying) {
//...貌似没有做什么操作
} else if (r.executeNesting != 1) {
//..
r.executeNesting = 1;
}
}
final long origId = Binder.clearCallingIdentity();
//这里的isDestroying为true
serviceDoneExecutingLocked(r, inDestroying, inDestroying);
Binder.restoreCallingIdentity(origId);
} //...
}
最后执行serviceDoneExecutingLocked,做Service的收尾工作,例如清除ServiceRecord持有的IntentBindRecord,从ProcessRecord里面清除ServiceRecord等。
另外一种方式就是在Service里面stop:
public abstract class Service extends ContextWrapper implements ComponentCallbacks2 {
private IActivityManager mActivityManager;
public final void stopSelf() {
stopSelf(-1);
}
public final void stopSelf(int startId) {
if (mActivityManager == null) {
return;
}
try {
mActivityManager.stopServiceToken(
new ComponentName(this, mClassName), mToken, startId);
} catch (RemoteException ex) {
}
}
}
mActivityManager就为Service启动过程中,调用attach初始化的ActivityManagerProxy,所以就通过Binder调用ActivityManagerService的stopServiceToken:
@Override
public boolean stopServiceToken(ComponentName className, IBinder token,
int startId) {
synchronized(this) {
return mServices.stopServiceTokenLocked(className, token, startId);
}
}
继续调用ActivieServices#stopServiceTokenLocked:
boolean stopServiceTokenLocked(ComponentName className, IBinder token,
int startId) {
ServiceRecord r = findServiceLocked(className, token, UserHandle.getCallingUserId());
if (r != null) {
//startId小于零就直接结束
if (startId >= 0) {
//找到执行过的StartItem
ServiceRecord.StartItem si = r.findDeliveredStart(startId, false);
if (si != null) {
while (r.deliveredStarts.size() > 0) {
ServiceRecord.StartItem cur = r.deliveredStarts.remove(0);
cur.removeUriPermissionsLocked();
if (cur == si) {
break;
}
}
}
//如果最后一次启动的startId不等于传进来的startId则不结束Service
if (r.getLastStartId() != startId) {
return false;
}
//...
}
r.startRequested = false;
//...
r.callStart = false;
final long origId = Binder.clearCallingIdentity();
bringDownServiceIfNeededLocked(r, false, false);
Binder.restoreCallingIdentity(origId);
return true;
}
return false;
}
如果传进来的startId不等于最后一次启动的startId则不会销毁Service,IntentService就是利用了这个特性来实现顺序执行任务。
如果startId小于零则直接调用bringDownServiceIfNeededLocked,就和上面在Service外面stopService流程一样了。