介绍
Service是一种可以在后台执行长时间运行操作而不提供界面的应用组件。服务可以由其他应用组件启动,而且即使用户切换到其他应用,服务仍将在后台继续运行。此外,组件可以通过绑定到服务与之进行交互,甚至是执行进程之间的通信。
正文
1.Service的介绍
<service android:name=".MyService"
android:isolatedProcess="true"
android:directBootAware="true"
android:process=":subService"/>
import android.app.Service
import android.content.Intent
import android.os.IBinder
class PreloadService : Service() {
override fun onBind(p0: Intent?): IBinder? {
return null
}
}
service的标签属性比较简单,具体可以参考官网。我在这里就举几个属性的例子:
isolatedProcess
:服务与系统其余部分隔离的特殊进程下运行。
process
:指定服务运行的进程名称。以:
开头,系统会根据需要时创建新进程,并且服务会在该进程运行。
directBootAware
:服务是否支持直接启动,也就是可以在用户解锁设备之前运行。
Service的生命周期
它的生命周期会和我们使用Service
的不同 也有所不同。左边是startService
右边是bindService
。我们汇编可以根据源码 再来看看执行的时机。
Service的运行模式
1.前台Service:执行一些用户能注意到的操作,前台服务必须显示通知。
2.后台Service:后台服务不会影响用户,在26以后,系统会对后台服务施加限制。
更多Android Framework 学习资料 请点击免费领取
2.Service的启动
1.startService
在源码中我们可以直接在Activity中调用startService
,那就跟一下 看看它是如何开启Service的。 文件目录:/android/frameworks/base/core/java/android/content/ContextWrapper.java
public ComponentName startServiceAsUser(Intent service, UserHandle user) {
return mBase.startServiceAsUser(service, user);
}
//mBase就是ContextImpl 参考Activity创建流程
Context mBase;
public ComponentName startService(Intent service) {
warnIfCallingFromSystemProcess();
return startServiceCommon(service, false, mUser);
}
//开启Service
private ComponentName startServiceCommon(Intent service, boolean requireForeground,
UserHandle user) {
try {
//校验intent
validateServiceIntent(service);
//设置intent的属性,准备离开现有进程
service.prepareToLeaveProcess(this);
//调用AMS的startService 传入了 当前进程,service(目标servcie),true
ComponentName cn = ActivityManager.getService().startService(
mMainThread.getApplicationThread(), service, service.resolveTypeIfNeeded(
getContentResolver()), requireForeground,
getOpPackageName(), user.getIdentifier());
return cn;
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
看看AMS
是如何开启Service
public ComponentName startService(IApplicationThread caller, Intent service,
String resolvedType, boolean requireForeground, String callingPackage, int userId)
throws TransactionTooLargeException {
//判断是否是隔离进程调用
enforceNotIsolatedCaller("startService");
synchronized(this) {
//获取pid
final int callingPid = Binder.getCallingPid();
//获取uid
final int callingUid = Binder.getCallingUid();
//获取origid
final long origId = Binder.clearCallingIdentity();
ComponentName res;
try {
//调用mService的startServiceLocked 这里的mService就是之前讲AMS启动流程时创建的ActiveServices 用来管理Service的
res = mServices.startServiceLocked(caller, service,
resolvedType, callingPid, callingUid,
requireForeground, callingPackage, userId);
} finally {
Binder.restoreCallingIdentity(origId);
}
return res;
}
}
文件目录:/android/frameworks/base/services/core/java/com/android/server/am/ActiveServices.java
ComponentName startServiceLocked(IApplicationThread caller, Intent service, String resolvedType,
int callingPid, int callingUid, boolean fgRequired, String callingPackage, final int userId)
throws TransactionTooLargeException {
return startServiceLocked(caller, service, resolvedType, callingPid, callingUid, fgRequired,
callingPackage, userId, false);
}
ComponentName startServiceLocked(IApplicationThread caller, Intent service, String resolvedType,
int callingPid, int callingUid, boolean fgRequired, String callingPackage,
final int userId, boolean allowBackgroundActivityStarts)
throws TransactionTooLargeException {
final boolean callerFg;
if (caller != null) {//不为null 获取到当前进程的ProcessRecord
final ProcessRecord callerApp = mAm.getRecordForAppLocked(caller);
callerFg = callerApp.setSchedGroup != ProcessList.SCHED_GROUP_BACKGROUND;
} else {
callerFg = true;
}
//得到ServiceRecord对象:先从mServiceMap中查找 如果有就返回 没有的话就创建(通过pkms.resolveService 查找service创建ServiceRecord包装成ServiceLookupResult返回)
ServiceLookupResult res =
retrieveServiceLocked(service, null, resolvedType, callingPackage,
callingPid, callingUid, userId, true, callerFg, false, false);
//拿到ServiceRecord ServiceRecord继承自Binder
ServiceRecord r = res.record;
final boolean bgLaunch = !mAm.isUidActiveLocked(r.appInfo.uid);
boolean forcedStandby = false;
if (bgLaunch && appRestrictedAnyInBackground(r.appInfo.uid, r.packageName)) {
forcedStandby = true;
}
boolean forceSilentAbort = false;
if (fgRequired) {//这里是false不走 前台走这里
}
if (forcedStandby || (!r.startRequested && !fgRequired)) {
//判断是否运行启动服务:常驻内存、蓝牙、电源白名单允许直接启动服务 否则执行默认策略:如果大于AndroidO不允许启动后台服务
final int allowed = mAm.getAppStartModeLocked(r.appInfo.uid, r.packageName,
r.appInfo.targetSdkVersion, callingPid, false, false, forcedStandby);
if (allowed != ActivityManager.APP_START_MODE_NORMAL) {//不允许启动服务的逻辑
if (allowed == ActivityManager.APP_START_MODE_DELAYED || forceSilentAbort) {
return null;
}
if (forcedStandby) {
if (fgRequired) {//false
return null;
}
}
UidRecord uidRec = mAm.mProcessList.getUidRecordLocked(r.appInfo.uid);
return new ComponentName("?", "app is in background uid " + uidRec);
}
}
if (r.appInfo.targetSdkVersion < Build.VERSION_CODES.O && fgRequired) {//不走这里
fgRequired = false;
}
//记录时间戳
r.lastActivity = SystemClock.uptimeMillis();
//设置已经开启了
r.startRequested = true;
r.delayedStop = false;
r.fgRequired = fgRequired;
//添加了一个ServiceRecord.StartItem taskRemoved = false 如果是BindService 不会添加 因为他直接调用的是realStartService
r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
service, neededGrants, callingUid));
if (fgRequired) {//这里不走
}
final ServiceMap smap = getServiceMapLocked(r.userId);
boolean addToStarting = false;
if (allowBackgroundActivityStarts) {
r.whitelistBgActivityStartsOnServiceStart();
}
//调用startServiceInnerLocked
ComponentName cmp = startServiceInnerLocked(smap, service, r, callerFg, addToStarting);
return cmp;
}
ComponentName startServiceInnerLocked(ServiceMap smap, Intent service, ServiceRecord r,
boolean callerFg, boolean addToStarting) throws TransactionTooLargeException {
ServiceState stracker = r.getTracker();
if (stracker != null) {
stracker.setStarted(true, mAm.mProcessStats.getMemFactorLocked(), r.lastActivity);
}
r.callStart = false;
synchronized (r.stats.getBatteryStats()) {
r.stats.startRunningLocked();
}
//调用bringUpServiceLocked 开启进程
String error = bringUpServiceLocked(r, service.getFlags(), callerFg, false, false);
if (error != null) {
return new ComponentName("!!", error);
}
if (r.startRequested && addToStarting) {
boolean first = smap.mStartingBackground.size() == 0;
smap.mStartingBackground.add(r);
r.startingBgTimeout = SystemClock.uptimeMillis() + mAm.mConstants.BG_START_TIMEOUT;
if (DEBUG_DELAYED_SERVICE) {
RuntimeException here = new RuntimeException("here");
here.fillInStackTrace();
} else if (DEBUG_DELAYED_STARTS) {
}
if (first) {
smap.rescheduleDelayedStartsLocked();
}
} else if (callerFg || r.fgRequired) {
smap.ensureNotStartingBackgroundLocked(r);
}
return r.name;
}
private String bringUpServiceLocked(ServiceRecord r, int intentFlags, boolean execInFg,
boolean whileRestarting, boolean permissionsReviewRequired)
throws TransactionTooLargeException {
if (r.app != null && r.app.thread != null) {//已经运行
sendServiceArgsLocked(r, execInFg, false);
return null;
}
if (!whileRestarting && mRestartingServices.contains(r)) {
return null;
}
if (mRestartingServices.remove(r)) {
clearRestartingIfNeededLocked(r);
}
if (r.delayed) {
getServiceMapLocked(r.userId).mDelayedStartList.remove(r);
r.delayed = false;
}
//是否需要进程隔离下 运行
final boolean isolated = (r.serviceInfo.flags&ServiceInfo.FLAG_ISOLATED_PROCESS) != 0;
//获取进程名
final String procName = r.processName;
//创建HostingRecord
HostingRecord hostingRecord = new HostingRecord("service", r.instanceName);
ProcessRecord app;
if (!isolated) {//非隔离进程
//获取到service的ProcessRecord
app = mAm.getProcessRecordLocked(procName, r.appInfo.uid, false);
if (app != null && app.thread != null) {//进程已经存在 启动了
try {
app.addPackage(r.appInfo.packageName, r.appInfo.longVersionCode, mAm.mProcessStats);
realStartServiceLocked(r, app, execInFg);
return null;
} catch (TransactionTooLargeException e) {
throw e;
} catch (RemoteException e) {
}
}
} else {//隔离进程
//第一次开启isolatedProc是null
app = r.isolatedProc;
if (WebViewZygote.isMultiprocessEnabled()
&& r.serviceInfo.packageName.equals(WebViewZygote.getPackageName())) {
hostingRecord = HostingRecord.byWebviewZygote(r.instanceName);
}
if ((r.serviceInfo.flags & ServiceInfo.FLAG_USE_APP_ZYGOTE) != 0) {
hostingRecord = HostingRecord.byAppZygote(r.instanceName, r.definingPackageName,
r.definingUid);
}
}
//服务还没启动调用startProcessLocked 创建进程
if (app == null && !permissionsReviewRequired) {
if ((app=mAm.startProcessLocked(procName, r.appInfo, true, intentFlags,
hostingRecord, false, isolated, false)) == null) {
String msg = "Unable to launch app "
+ r.appInfo.packageName + "/"
+ r.appInfo.uid + " for service "
+ r.intent.getIntent() + ": process is bad";
bringDownServiceLocked(r);
return msg;
}
if (isolated) {
r.isolatedProc = app;
}
}
if (r.fgRequired) {//不走这里 是false
mAm.tempWhitelistUidLocked(r.appInfo.uid,
SERVICE_START_FOREGROUND_TIMEOUT, "fg-service-launch");
}
if (!mPendingServices.contains(r)) {
//假如mPendingServices中
mPendingServices.add(r);
}
if (r.delayedStop) {
r.delayedStop = false;
if (r.startRequested) {
stopServiceLocked(r);
}
}
return null;
}
在AMS
这里会先检查Service是否可以执行(常驻内存、蓝牙、电源白名单允许直接启动服务),接着调用bringUpServiceLocked
判断是否需要隔离进程如果非隔离 就看是否已经启动进程 执行realStartServiceLocked
,否则是隔离进程 直接开启新进程。我们没有设置隔离进程 所以我们会直接开启新进程,开启进程的过程在之前已经接触很多次了,我们直接跳过,开启成功之后会将ServiceRecord添加到mPendingServices
中去。所以我们看看进程创建成功之后会如何开启Service。
private boolean attachApplicationLocked(@NonNull IApplicationThread thread,
int pid, int callingUid, long startSeq) {
//到这里来
thread.bindApplication(processName, appInfo, providers,
instr2.mClass,
profilerInfo, instr2.mArguments,
instr2.mWatcher,
instr2.mUiAutomationConnection, testMode,
mBinderTransactionTrackingEnabled, enableTrackAllocation,
isRestrictedBackupMode || !normalMode, app.isPersistent(),
new Configuration(app.getWindowProcessController().getConfiguration()),
app.compat, getCommonServicesLocked(app.isolated),
mCoreSettingsObserver.getCoreSettingsLocked(),
buildSerial, autofillOptions, contentCaptureOptions);
boolean badApp = false;
boolean didSomething = false;
//在这里开启activity
if (normalMode) {
try {
didSomething = mAtmInternal.attachApplication(app.getWindowProcessController());
} catch (Exception e) {
badApp = true;
}
}
if (!badApp) {
try {
//开启Service
didSomething |= mServices.attachApplicationLocked(app, processName);
} catch (Exception e) {
badApp = true;
}
}
return true;
}
//还是在ActiveService中
boolean attachApplicationLocked(ProcessRecord proc, String processName)
throws RemoteException {
boolean didSomething = false;
//此时Services的size是大于0的
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.longVersionCode,
mAm.mProcessStats);
//调用realStartServiceLocked开启service
realStartServiceLocked(sr, proc, sr.createdFromFg);
didSomething = true;
if (!isServiceNeededLocked(sr, false, false)) {
bringDownServiceLocked(sr);
}
}
} catch (RemoteException e) {
throw e;
}
}
return didSomething;
}
//开启service
private final void realStartServiceLocked(ServiceRecord r,
ProcessRecord app, boolean execInFg) throws RemoteException {
//服务和当前进程绑定
r.setProcess(app);
r.restartTime = r.lastActivity = SystemClock.uptimeMillis();
//添加到ProcessRecord中
final boolean newService = app.services.add(r);
//埋炸弹scheduleServiceTimeoutLocked
bumpServiceExecutingLocked(r, execInFg, "create");
//更新进程LRU
mAm.updateLruProcessLocked(app, false, null);
updateServiceForegroundLocked(r.app, /* oomAdj= */ false);
//更新OOMAdj
mAm.updateOomAdjLocked(OomAdjuster.OOM_ADJ_REASON_START_SERVICE);
boolean created = false;
try {
synchronized (r.stats.getBatteryStats()) {
r.stats.startLaunchedLocked();
}
mAm.notifyPackageUse(r.serviceInfo.packageName,
PackageManager.NOTIFY_PACKAGE_USE_SERVICE);
app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_SERVICE);
//调用到应用进程 也就是服务进程 ActivityThread
app.thread.scheduleCreateService(r, r.serviceInfo,
mAm.compatibilityInfoForPackage(r.serviceInfo.applicationInfo),
app.getReportedProcState());
r.postNotification();
created = true;
} catch (DeadObjectException e) {
} finally {
}
if (r.whitelistManager) {
app.whitelistManager = true;
}
//处理Bind我们不处理 没有Bind 此时直说startService
requestServiceBindingsLocked(r, execInFg);
updateServiceClientActivitiesLocked(app, null, true);
if (newService && created) {
app.addBoundClientUidsOfNewService(r);
}
if (r.startRequested && r.callStart && r.pendingStarts.size() == 0) {
r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
null, null, 0));
}
//发送Service的args
sendServiceArgsLocked(r, execInFg, true);
if (r.delayed) {
getServiceMapLocked(r.userId).mDelayedStartList.remove(r);
r.delayed = false;
}
}
回到ActivityThread看看它的scheduleCreateService
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;
//给mH发送了H.CREATE_SERVICE
sendMessage(H.CREATE_SERVICE, s);
}
case CREATE_SERVICE:
handleCreateService((CreateServiceData)msg.obj);
break;
//创建Service
private void handleCreateService(CreateServiceData data) {
unscheduleGcIdler();
LoadedApk packageInfo = getPackageInfoNoCheck(
data.info.applicationInfo, data.compatInfo);
Service service = null;
try {
//反射创建Service
java.lang.ClassLoader cl = packageInfo.getClassLoader();
service = packageInfo.getAppFactory()
.instantiateService(cl, data.info.name, data.intent);
} catch (Exception e) {
}
try {
//创建Context
ContextImpl context = ContextImpl.createAppContext(this, packageInfo);
context.setOuterContext(service);
//调用makeApplication
Application app = packageInfo.makeApplication(false, mInstrumentation);
//调用service的attach 绑定ActivityThread token Application 以及AMS
service.attach(context, this, data.info.name, data.token, app,
ActivityManager.getService());
//调用service的onCreate
service.onCreate();
//存入到mService中去
mServices.put(data.token, service);
try {
//告诉AMS创建完成
ActivityManager.getService().serviceDoneExecuting(
data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
} catch (Exception e) {
}
}
public final void attach(
Context context,
ActivityThread thread, String className, IBinder token,
Application application, Object activityManager) {
attachBaseContext(context);
mThread = thread; // NOTE: unused - remove?
mClassName = className;
mToken = token;
mApplication = application;
mActivityManager = (IActivityManager)activityManager;
mStartCompatibility = getApplicationInfo().targetSdkVersion
< Build.VERSION_CODES.ECLAIR;
}
到AMS 处理服务创建
public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
synchronized(this) {
if (!(token instanceof ServiceRecord)) {
throw new IllegalArgumentException("Invalid service token");
}
mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
}
}
//AMS开启Service成功
void serviceDoneExecutingLocked(ServiceRecord r, int type, int startId, int res) {
boolean inDestroying = mDestroyingServices.contains(r);
if (r != null) {
//在这里把炸弹拆除
serviceDoneExecutingLocked(r, inDestroying, inDestroying);
}
}
发送的args
private final void sendServiceArgsLocked(ServiceRecord r, boolean execInFg,
boolean oomAdjusted) throws TransactionTooLargeException {
final int N = r.pendingStarts.size();
if (N == 0) {//不是0
return;
}
ArrayList<ServiceStartArgs> args = new ArrayList<>();
while (r.pendingStarts.size() > 0) {
ServiceRecord.StartItem si = r.pendingStarts.remove(0);
if (si.intent == null && N > 1) {
continue;
}
si.deliveredTime = SystemClock.uptimeMillis();
r.deliveredStarts.add(si);
si.deliveryCount++;
//埋炸弹
bumpServiceExecutingLocked(r, execInFg, "start");
if (!oomAdjusted) {
oomAdjusted = true;
mAm.updateOomAdjLocked(r.app, true, OomAdjuster.OOM_ADJ_REASON_START_SERVICE);
}
if (r.fgRequired && !r.fgWaiting) {//前台Service
if (!r.isForeground) {
scheduleServiceForegroundTransitionTimeoutLocked(r);
} else {
r.fgRequired = false;
}
}
int flags = 0;
if (si.deliveryCount > 1) {
flags |= Service.START_FLAG_RETRY;
}
if (si.doneExecutingCount > 0) {
flags |= Service.START_FLAG_REDELIVERY;
}
args.add(new ServiceStartArgs(si.taskRemoved, si.id, flags, si.intent));
}
//执行ActivityThread的scheduleServiceArgs
r.app.thread.scheduleServiceArgs(r, slice);
}
public final void scheduleServiceArgs(IBinder token, ParceledListSlice args) {
List<ServiceStartArgs> list = args.getList();
for (int i = 0; i < list.size(); i++) {
ServiceStartArgs ssa = list.get(i);
ServiceArgsData s = new ServiceArgsData();
s.token = token;
s.taskRemoved = ssa.taskRemoved;
s.startId = ssa.startId;
s.flags = ssa.flags;
s.args = ssa.args;
//给mH发送SERVICE_ARGS
sendMessage(H.SERVICE_ARGS, s);
}
}
case SERVICE_ARGS:
handleServiceArgs((ServiceArgsData)msg.obj);
break;
//处理Args
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) {//这里是false 所以会执行onStartCommand
res = s.onStartCommand(data.args, data.flags, data.startId);
} else {
}
QueuedWork.waitToFinish();
try {
//通知AMS 拆除炸弹
ActivityManager.getService().serviceDoneExecuting(
data.token, SERVICE_DONE_EXECUTING_START, data.startId, res);
} catch (RemoteException e) {
}
} catch (Exception e) {
}
}
}
进程创建之后,会调用AMS
的attachApplication
接着处理service(ActiveService)
,之前创建之后会添加到mPendingServices
中,现在继续处理调用realStartServiceLocked
来开启Service,在开启的过程中会埋入一个炸弹(给Handler发送一个SERVICE_TIMEOUT_MSG
) 如果超时未处理会弹出ANR
,然后调用app.thread.scheduleCreateService
通知客户端创建反射Service、Context
调用onCreate
把Service
存入到mService
中,调用AMS
的serviceDoneExecuting
进行炸弹的拆除。 然后再埋炸弹 调用app.thread.scheduleServiceArgs
调用service.onStartCommand
再通知AMS 拆除炸弹。 这样Service就运行起来了。我们再看看Service的onStop。
还是回到ContextImpl
public boolean stopService(Intent service) {
return stopServiceCommon(service, mUser);
}
private boolean stopServiceCommon(Intent service, UserHandle user) {
validateServiceIntent(service);
service.prepareToLeaveProcess(this);
//调用AMS的stopService
int res = ActivityManager.getService().stopService(
mMainThread.getApplicationThread(), service,
service.resolveTypeIfNeeded(getContentResolver()), user.getIdentifier());
return res != 0;
}
public int stopService(IApplicationThread caller, Intent service,
String resolvedType, int userId) {
enforceNotIsolatedCaller("stopService");
synchronized(this) {
//调用ActiveService的stopServiceLocked
return mServices.stopServiceLocked(caller, service, resolvedType, userId);
}
}
int stopServiceLocked(IApplicationThread caller, Intent service,
String resolvedType, int userId) {
//获取到调用这的ProcessRecord
final ProcessRecord callerApp = mAm.getRecordForAppLocked(caller);
//获取ServiceRecord
ServiceLookupResult r = retrieveServiceLocked(service, null, resolvedType, null,
Binder.getCallingPid(), Binder.getCallingUid(), userId, false, false, false, false);
if (r != null) {
if (r.record != null) {
final long origId = Binder.clearCallingIdentity();
try {
//调用stopServiceLocked
stopServiceLocked(r.record);
} finally {
Binder.restoreCallingIdentity(origId);
}
return 1;
}
return -1;
}
return 0;
}
private void stopServiceLocked(ServiceRecord service) {
if (service.delayed) {
service.delayedStop = true;
return;
}
synchronized (service.stats.getBatteryStats()) {
service.stats.stopRunningLocked();
}
service.startRequested = false;
if (service.tracker != null) {
service.tracker.setStarted(false, mAm.mProcessStats.getMemFactorLocked(),
SystemClock.uptimeMillis());
}
service.callStart = false;
bringDownServiceIfNeededLocked(service, false, false);
}
private final void bringDownServiceIfNeededLocked(ServiceRecord r, boolean knowConn,
boolean hasConn) {
if (isServiceNeededLocked(r, knowConn, hasConn)) {
return;
}
if (mPendingServices.contains(r)) {
return;
}
bringDownServiceLocked(r);
}
private final void bringDownServiceLocked(ServiceRecord r) {
if (r.app != null && r.app.thread != null) {
boolean needOomAdj = false;
//执行unBind
for (int i = r.bindings.size() - 1; i >= 0; i--) {
IntentBindRecord ibr = r.bindings.valueAt(i);
if (ibr.hasBound) {
try {
bumpServiceExecutingLocked(r, false, "bring down unbind");
needOomAdj = true;
ibr.hasBound = false;
ibr.requested = false;
r.app.thread.scheduleUnbindService(r,
ibr.intent.getIntent());
} catch (Exception e) {
serviceProcessGoneLocked(r);
}
}
}
if (needOomAdj) {
mAm.updateOomAdjLocked(r.app, true,
OomAdjuster.OOM_ADJ_REASON_UNBIND_SERVICE);
}
}
r.fgRequired = false;
r.fgWaiting = false;
ServiceState stracker = r.getTracker();
if (stracker != null) {
stracker.setForeground(false, mAm.mProcessStats.getMemFactorLocked(),
r.lastActivity);
}
mAm.mAppOpsService.finishOperation(AppOpsManager.getToken(mAm.mAppOpsService),
AppOpsManager.OP_START_FOREGROUND, r.appInfo.uid, r.packageName);
mAm.mHandler.removeMessages(
ActivityManagerService.SERVICE_FOREGROUND_TIMEOUT_MSG, r);
if (r.app != null) {
Message msg = mAm.mHandler.obtainMessage(
ActivityManagerService.SERVICE_FOREGROUND_CRASH_MSG);
msg.obj = r.app;
msg.getData().putCharSequence(
ActivityManagerService.SERVICE_RECORD_KEY, r.toString());
mAm.mHandler.sendMessage(msg);
}
}
//记录销毁时间
r.destroyTime = SystemClock.uptimeMillis();
final ServiceMap smap = getServiceMapLocked(r.userId);
//从map中移除
ServiceRecord found = smap.mServicesByInstanceName.remove(r.instanceName);
//移除
smap.mServicesByIntent.remove(r.intent);
r.totalRestartCount = 0;
r.isForeground = false;
r.foregroundId = 0;
r.foregroundNoti = null;
r.clearDeliveredStartsLocked();
r.pendingStarts.clear();
smap.mDelayedStartList.remove(r);
if (r.app != null) {
synchronized (r.stats.getBatteryStats()) {
r.stats.stopLaunchedLocked();
}
r.app.services.remove(r);
r.app.updateBoundClientUids();
if (r.whitelistManager) {
updateWhitelistManagerLocked(r.app);
}
if (r.app.thread != null) {
updateServiceForegroundLocked(r.app, false);
try {
//埋炸弹
bumpServiceExecutingLocked(r, false, "destroy");
mDestroyingServices.add(r);
r.destroying = true;
mAm.updateOomAdjLocked(r.app, true,
OomAdjuster.OOM_ADJ_REASON_UNBIND_SERVICE);
//到客户端执行scheduleStopService
r.app.thread.scheduleStopService(r);
} catch (Exception e) {
serviceProcessGoneLocked(r);
}
} else {
}
}
if (r.bindings.size() > 0) {
//清空bindings
r.bindings.clear();
}
if (r.restarter instanceof ServiceRestarter) {
((ServiceRestarter)r.restarter).setService(null);
}
int memFactor = mAm.mProcessStats.getMemFactorLocked();
long now = SystemClock.uptimeMillis();
if (r.tracker != null) {
r.tracker.setStarted(false, memFactor, now);
r.tracker.setBound(false, memFactor, now);
if (r.executeNesting == 0) {
r.tracker.clearCurrentOwner(r, false);
r.tracker = null;
}
}
smap.ensureNotStartingBackgroundLocked(r);
}
public final void scheduleStopService(IBinder token) {
sendMessage(H.STOP_SERVICE, token);
}
case STOP_SERVICE:
handleStopService((IBinder)msg.obj);
schedulePurgeIdler();//清空待清理的资源
break;
private void handleStopService(IBinder token) {
//从mService中移除掉 只是从map中移除掉了引用,所以我们需要注意Service内部的thread 以及变量不要引起内存泄漏或者线程没有停止
Service s = mServices.remove(token);
if (s != null) {
try {
//调用s的onDestory
s.onDestroy();
s.detachAndCleanUp();
Context context = s.getBaseContext();
if (context instanceof ContextImpl) {
final String who = s.getClassName();
((ContextImpl) context).scheduleFinalCleanup(who, "Service");
}
QueuedWork.waitToFinish();
try {
//调用AMS的serviceDoneExecuting 拆除炸弹
ActivityManager.getService().serviceDoneExecuting(
token, SERVICE_DONE_EXECUTING_STOP, 0, 0);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
} catch (Exception e) {
}
} else {
}
}
stop的流程和start的流程差不多,需要注意的是stop
只是从map中移除了
,我们需要自己释放资源。