android中service的两种实现方法(android中service的实现方法)
1:前言
Service是Android中的四大组件之一,日常开发中我们经常会使用startService之类的方法来启动Service,那这个方法调用的底层原理是什么呢?Android系统是如何启动起来Service的呢?本文我们从源码出发,介绍一下Android中的Service是如何启动Service的,本文的结构如下:
2:源码分析
2.1:ContextImpl.startService&startForegroundService:应用层调用的入口
我们调用
startService/startForegroundService之后,会调用到android.app.ContextImpl#
startService/startForegroundService:
class ContextImpl extends Context {
@Override
public ComponentName startService(Intent service) {
return startServiceCommon(service, false, mUser);
}
@Override
public ComponentName startForegroundService(Intent service) {
return startServiceCommon(service, true, mUser);
}
private ComponentName startServiceCommon(Intent service, boolean requireForeground,
UserHandle user) {
...
}
}可以看到,startService和startForegroundService最终调用的都是startServiceCommon这个方法,唯一不同的是第二个参数requireForeground的值不一样,用来标识当前Service是否是前台Serivice,我们来看startServiceCommon的具体实现:
class ContextImpl extends Context {
private ComponentName startServiceCommon(Intent service, boolean requireForeground,
UserHandle user) {
try {
validateServiceIntent(service);
service.prepareToLeaveProcess(this);
ComponentName cn = ActivityManager.getService().startService(
mMainThread.getApplicationThread(), service,
service.resolveTypeIfNeeded(getContentResolver()), requireForeground,
getOpPackageName(), getAttributionTag(), user.getIdentifier());
if (cn != null) {
if (cn.getPackageName().equals("!")) {
throw new SecurityException(
"Not allowed to start service " service
" without permission " cn.getClassName());
} else if (cn.getPackageName().equals("!!")) {
throw new SecurityException(
"Unable to start service " service
": " cn.getClassName());
} else if (cn.getPackageName().equals("?")) {
throw new IllegalStateException(
"Not allowed to start service " service ": " cn.getClassName());
}
}
return cn;
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
}可以看到,核心是调用到了
ActivityManager.getService().startService()方法进行Service的启动,即AMS中,我们来看一下AMS中是如何启动Service的.
2.2:ActivityManagerService.startService:执行前置判断,满足启动service的条件的话触发真正startService的逻辑
//frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
public class ActivityManagerService extends IActivityManager.Stub{
final ActiveServices mServices;
@Override
public ComponentName startService(IApplicationThread caller, Intent service,
String resolvedType, boolean requireForeground, String callingPackage,
String callingFeatureId, int userId)
throws TransactionTooLargeException {
...
synchronized(this) {
final int callingPid = Binder.getCallingPid();
final int callingUid = Binder.getCallingUid();
final long origId = Binder.clearCallingIdentity();
ComponentName res;
try {
res = mServices.startServiceLocked(caller, service,
resolvedType, callingPid, callingUid,
requireForeground, callingPackage, callingFeatureId, userId);
} finally {
Binder.restoreCallingIdentity(origId);
}
return res;
}
}
}可以看到,最终调用到了
ActiveServices.startServiceLocked()中:
//frameworks/base/services/core/java/com/android/server/am/ActiveServices.java
public final class ActiveServices {
ComponentName startServiceLocked(IApplicationThread caller, Intent service, String resolvedType,
int callingPid, int callingUid, boolean fgRequired, String callingPackage,
@Nullable String callingFeatureId, final int userId)
throws TransactionTooLargeException {
return startServiceLocked(caller, service, resolvedType, callingPid, callingUid, fgRequired,
callingPackage, callingFeatureId, userId, false);
}
ComponentName startServiceLocked(IApplicationThread caller, Intent service, String resolvedType,
int callingPid, int callingUid, boolean fgRequired, String callingPackage,
@Nullable String callingFeatureId, final int userId,
boolean allowBackgroundActivityStarts) throws TransactionTooLargeException {
/**
*对当前Service的启动进行判断,看下Service启动的限制(比如权限、前后台等是否满足)
**/
...
//启动Service
ComponentName cmp = startServiceInnerLocked(smap, service, r, callerFg, addToStarting);
if (!r.mAllowWhileInUsePermissionInFgs) {
r.mAllowWhileInUsePermissionInFgs =
shouldAllowWhileInUsePermissionInFgsLocked(callingPackage, callingPid,
callingUid, service, r, allowBackgroundActivityStarts);
}
return cmp;
}
ComponentName startServiceInnerLocked(ServiceMap smap, Intent service, ServiceRecord r,
boolean callerFg, boolean addToStarting) throws TransactionTooLargeException {
...
String error = bringUpServiceLocked(r, service.getFlags(), callerFg, false, false);
...
return r.name;
}
}核心是调用到了
ActiveServices.bringUpServiceLocked.
2.3:ActiveServices.bringUpServiceLocked:根据进程&线程是否存在执行不同操作
//frameworks/base/services/core/java/com/android/server/am/ActiveServices.java
public final class ActiveServices {
private String bringUpServiceLocked(ServiceRecord r, int intentFlags, boolean execInFg,
boolean whileRestarting, boolean permissionsReviewRequired)
throws TransactionTooLargeException {
//如果进程和线程已经不为空,说明该Service已经create了,直接调用sendServiceArgsLocked
if (r.app != null && r.app.thread != null) {
sendServiceArgsLocked(r, execInFg, false);
return null;
}
...
final boolean isolated = (r.serviceInfo.flags&ServiceInfo.FLAG_ISOLATED_PROCESS) != 0;
final String procName = r.processName;
HostingRecord hostingRecord = new HostingRecord("service", r.instanceName);
ProcessRecord app;
if (!isolated) {
app = mAm.getProcessRecordLocked(procName, r.appInfo.uid, false);
//如果进程已经在了,调用realStartServiceLocked进行start service
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) {
Slog.w(TAG, "Exception when starting service " r.shortInstanceName, e);
}
// If a dead object exception was thrown -- fall through to
// restart the application.
}
}
// 如果进程还没启动,调用mAm.startProcessLocked启动进程
if (app == null && !permissionsReviewRequired) {
if ((app=mAm.startProcessLocked(procName, r.appInfo, true, intentFlags,
hostingRecord, ZYGOTE_POLICY_FLAG_EMPTY, false, isolated, false)) == null) {
//埋下异常
bringDownServiceLocked(r);
...
}
}
//将当前ServiceRecord加到mPendingServices里,
if (!mPendingServices.contains(r)) {
mPendingServices.add(r);
}
...
}
}在《Android的进程》一文中我们介绍过,最终进程起来之后会执行
ActivityManagerService.attachApplication-->
ActivityManagerService.attachApplicationLocked:
public class ActivityManagerService extends IActivityManager.Stub{
public ActivityTaskManagerInternal mAtmInternal;
final ActiveServices mServices;
private boolean attachApplicationLocked(@NonNull IApplicationThread thread,
int pid, int callingUid, long startSeq) {
boolean badApp = false;
boolean didSomething = false;
// 先尝试启动Activity
if (normalMode) {
try {
didSomething = mAtmInternal.attachApplication(app.getWindowProcessController());
} catch (Exception e) {
Slog.wtf(TAG, "Exception thrown launching activities in " app, e);
badApp = true;
}
}
//Activity启动没问题,尝试启动Service
if (!badApp) {
try {
didSomething |= mServices.attachApplicationLocked(app, processName);
} catch (Exception e) {
Slog.wtf(TAG, "Exception thrown starting services in " app, e);
badApp = true;
}
}
}
}可以看到,先启动了Activity,如果Activity的启动过程中没有出错,就启动Service即调用
ActiveServices.attachApplicationLocked.
2.4:ActiveServices.attachApplicationLocked:进程启动完成,继续启动service
public final class ActiveServices {
boolean attachApplicationLocked(ProcessRecord proc, String processName){
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.longVersionCode,
mAm.mProcessStats);
//核心操作是调用realStartServiceLocked
realStartServiceLocked(sr, proc, sr.createdFromFg);
didSomething = true;
if (!isServiceNeededLocked(sr, false, false)) {
// We were waiting for this service to start, but it is actually no
// longer needed. This could happen because bringDownServiceIfNeeded
// won't bring down a service that is pending... so now the pending
// is done, so let's drop it.
bringDownServiceLocked(sr);
}
}
} catch (RemoteException e) {
Slog.w(TAG, "Exception in new application when starting service "
sr.shortInstanceName, e);
throw e;
}
}
// Also, if there are any services that are waiting to restart and
// would run in this process, now is a good time to start them. It would
// be weird to bring up the process but arbitrarily not let the services
// run at this point just because their restart time hasn't come up.
if (mRestartingServices.size() >0) {
ServiceRecord sr;
for (int i=0; i<mRestartingServices.size(); i ) {
sr = mRestartingServices.get(i);
if (proc != sr.isolatedProc && (proc.uid != sr.appInfo.uid
|| !processName.equals(sr.processName))) {
continue;
}
mAm.mHandler.removeCallbacks(sr.restarter);
mAm.mHandler.post(sr.restarter);
}
}
return didSomething;
}
}可以看到最终调用到了realStartServiceLocked.
2.5:ActiveServices.realStartServiceLocked:先埋炸弹,然后触发service启动
public final class ActiveServices {
/**
* Note the name of this method should not be confused with the started services concept.
* The "start" here means bring up the instance in the client, and this method is called
* from bindService() as well.
*/
private final void realStartServiceLocked(ServiceRecord r,
ProcessRecord app, boolean execInFg) 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);
r.setProcess(app);
r.restartTime = r.lastActivity = SystemClock.uptimeMillis();
//调用ProcessRecord.startService,实质是将此处的ServiceRecord add到ProcessRecord.mServices中
final boolean newService = app.startService(r);
//埋下ANR炸弹
bumpServiceExecutingLocked(r, execInFg, "create");
//调整进程的优先级
mAm.updateLruProcessLocked(app, false, null);
updateServiceForegroundLocked(r.app, /* oomAdj= */ false);
mAm.updateOomAdjLocked(app, OomAdjuster.OOM_ADJ_REASON_START_SERVICE);
boolean created = false;
...
//最终触发service.onCreate
app.thread.scheduleCreateService(r, r.serviceInfo,
mAm.compatibilityInfoForPackage(r.serviceInfo.applicationInfo),
app.getReportedProcState());
...
//bind service
requestServiceBindingsLocked(r, execInFg);
updateServiceClientActivitiesLocked(app, null, true);
if (newService && created) {
app.addBoundClientUidsOfNewService(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, 0));
}
//拉起timeout,最终调用Service.onStartCommand
sendServiceArgsLocked(r, execInFg, true);
if (r.delayed) {
if (DEBUG_DELAYED_STARTS) Slog.v(TAG_SERVICE, "REM FR DELAY LIST (new proc): " r);
getServiceMapLocked(r.userId).mDelayedStartList.remove(r);
r.delayed = false;
}
if (r.delayedStop) {
// Oh and hey we've already been asked to stop!
r.delayedStop = false;
if (r.startRequested) {
if (DEBUG_DELAYED_STARTS) Slog.v(TAG_SERVICE,
"Applying delayed stop (from start): " r);
stopServiceLocked(r);
}
}
}2.6:ActiveServices.bumpServiceExecutingLocked:埋下ANR炸弹(SERVICE_TIMEOUT_MSG)
public final class ActiveServices {
// How long we wait for a service to finish executing.
static final int SERVICE_TIMEOUT = 20 * 1000 * Build.HW_TIMEOUT_MULTIPLIER;
// How long we wait for a service to finish executing.
static final int SERVICE_BACKGROUND_TIMEOUT = SERVICE_TIMEOUT * 10;
// How long the startForegroundService() grace period is to get around to
// calling startForeground() before we ANR stop it.
static final int SERVICE_START_FOREGROUND_TIMEOUT = 10 * 1000 * Build.HW_TIMEOUT_MULTIPLIER;
private final void bumpServiceExecutingLocked(ServiceRecord r, boolean fg, String why) {
long now = SystemClock.uptimeMillis();
if (r.executeNesting == 0) {
r.executeFg = fg;
ServiceState stracker = r.getTracker();
if (stracker != null) {
stracker.setExecuting(true, mAm.mProcessStats.getMemFactorLocked(), now);
}
if (r.app != null) {
r.app.executingServices.add(r);
r.app.execServicesFg |= fg;
if (timeoutNeeded && r.app.executingServices.size() == 1) {
//启动延迟炸弹(触发ANR)
scheduleServiceTimeoutLocked(r.app);
}
}
} else if (r.app != null && fg && !r.app.execServicesFg) {
r.app.execServicesFg = true;
if (timeoutNeeded) {
scheduleServiceTimeoutLocked(r.app);
}
}
r.executeFg |= fg;
r.executeNesting ;
r.executingStart = now;
}
void scheduleServiceTimeoutLocked(ProcessRecord proc) {
if (proc.executingServices.size() == 0 || proc.thread == null) {
return;
}
Message msg = mAm.mHandler.obtainMessage(
ActivityManagerService.SERVICE_TIMEOUT_MSG);
msg.obj = proc;
//前台Service延迟SERVICE_TIMEOUT(20s),后台Service延迟SERVICE_BACKGROUND_TIMEOUT(200s)
mAm.mHandler.sendMessageDelayed(msg,
proc.execServicesFg ? SERVICE_TIMEOUT : SERVICE_BACKGROUND_TIMEOUT);
}
}2.7:ActivityThread.scheduleCreateService:触发Service.onCreate
可以看到这里主要是发送了一个CREATE_SERVICE的Message消息:
//frameworks/base/core/java/android/app/ActivityThread.java
public final class ActivityThread extends ClientTransactionHandler
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);
}
public void handleMessage(Message msg) {
...
case CREATE_SERVICE:
handleCreateService((CreateServiceData)msg.obj);
break;
...
}
public static final int SERVICE_DONE_EXECUTING_ANON = 0;
@UnsupportedAppUsage
private void handleCreateService(CreateServiceData data) {
LoadedApk packageInfo = getPackageInfoNoCheck(
data.info.applicationInfo, data.compatInfo);
Service service = null;
try {
ContextImpl context = ContextImpl.createAppContext(this, packageInfo);
Application app = packageInfo.makeApplication(false, mInstrumentation);
java.lang.ClassLoader cl = packageInfo.getClassLoader();
//实例化Service的对象
service = packageInfo.getAppFactory()
.instantiateService(cl, data.info.name, data.intent);
// Service resources must be initialized with the same loaders as the application
// context.
context.getResources().addLoaders(
app.getResources().getLoaders().toArray(new ResourcesLoader[0]));
context.setOuterContext(service);
//调用Service.attach
service.attach(context, this, data.info.name, data.token, app,
ActivityManager.getService());
//调用Service.onCreate
service.onCreate();
mServices.put(data.token, service);
//通知ActivityManagerService,Service启动完成,拆除预埋的炸弹,调整进程优先级
ActivityManager.getService().serviceDoneExecuting(
data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);
} catch (Exception e) {
}
}
}
//frameworks/base/core/java/android/app/AppComponentFactory.java
class AppComponentFactory{
public @NonNull Service instantiateService(@NonNull ClassLoader cl,
@NonNull String className, @Nullable Intent intent)
throws InstantiationException, IllegalAccessException, ClassNotFoundException {
return (Service) cl.loadClass(className).newInstance();
}
}2.8:ActivityManagerService.serviceDoneExecuting:拆除预埋的炸弹
//frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
public class ActivityManagerService extends IActivityManager.Stub{
final ActiveServices mServices;
public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
synchronized(this) {
if (!(token instanceof ServiceRecord)) {
Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" token);
throw new IllegalArgumentException("Invalid service token");
}
mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
}
}
}最终调用到了
ActiveServices.serviceDoneExecutingLocked:
//frameworks/base/services/core/java/com/android/server/am/ActiveServices.java
public final class ActiveServices {
void serviceDoneExecutingLocked(ServiceRecord r, int type, int startId, int res) {
if (r != null) {
...
serviceDoneExecutingLocked(r, inDestroying, inDestroying);
}
}
private void serviceDoneExecutingLocked(ServiceRecord r, boolean inDestroying,
boolean finishing) {
//拆除预埋的SERVICE_TIMEOUT_MSG炸弹
mAm.mHandler.removeMessages(ActivityManagerService.SERVICE_TIMEOUT_MSG, r.app);
//调整进程优先级
mAm.updateOomAdjLocked(r.app, true, OomAdjuster.OOM_ADJ_REASON_UNBIND_SERVICE);
}
}2.9:ActiveServices.sendServiceArgsLocked:启动延迟任务,埋下ANR和崩溃炸弹、触发onstartCommand
public final class ActiveServices {
final ActivityManagerService mAm;
private final void sendServiceArgsLocked(ServiceRecord r, boolean execInFg,
boolean oomAdjusted) throws TransactionTooLargeException {
final int N = r.pendingStarts.size();
if (N == 0) {
return;
}
ArrayListargs = new ArrayList<>();
while (r.pendingStarts.size() > 0) {
ServiceRecord.StartItem si = r.pendingStarts.remove(0);
//核心操作,埋下ANR炸弹,上面介绍过了
bumpServiceExecutingLocked(r, execInFg, "start");
if (!oomAdjusted) {
oomAdjusted = true;
//更新进程优先级
mAm.updateOomAdjLocked(r.app, true, OomAdjuster.OOM_ADJ_REASON_START_SERVICE);
}
if (r.fgRequired && !r.fgWaiting) {
if (!r.isForeground) {
//对于前台Service,启动延迟任务,检测Service调用了startForeground,否则会崩溃
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));
}
ParceledListSliceslice = new ParceledListSlice<>(args);
slice.setInlineCountLimit(4);
Exception caughtException = null;
try {
//调用ActivityThread.scheduleServiceArgs,最终执行Service.onstartCommand
r.app.thread.scheduleServiceArgs(r, slice);
}
}
// How long the startForegroundService() grace period is to get around to
// calling startForeground() before we ANR stop it.
static final int SERVICE_START_FOREGROUND_TIMEOUT = 10 * 1000 * Build.HW_TIMEOUT_MULTIPLIER;
void scheduleServiceForegroundTransitionTimeoutLocked(ServiceRecord r) {
if (r.app.executingServices.size() == 0 || r.app.thread == null) {
return;
}
Message msg = mAm.mHandler.obtainMessage(
ActivityManagerService.SERVICE_FOREGROUND_TIMEOUT_MSG);
msg.obj = r;
r.fgWaiting = true;
//延迟10s发送,埋下崩溃炸弹
mAm.mHandler.sendMessageDelayed(msg, SERVICE_START_FOREGROUND_TIMEOUT);
}
}2.10:ActivityThread.scheduleServiceArgs:触发onStartcommand
//frameworks/base/core/java/android/app/ActivityThread.java
public final class ActivityThread extends ClientTransactionHandler
public final void scheduleServiceArgs(IBinder token, ParceledListSlice args) {
Listlist = 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;
sendMessage(H.SERVICE_ARGS, s);
}
}
public void handleMessage(Message msg) {
...
case SERVICE_ARGS:
handleServiceArgs((ServiceArgsData)msg.obj);
break;
...
}
private void handleServiceArgs(ServiceArgsData data) {
Service s = mServices.get(data.token);
...
//调用onStartcommand
res = s.onStartCommand(data.args, data.flags, data.startId);
//拆除预埋的炸弹
ActivityManager.getService().serviceDoneExecuting(
data.token, SERVICE_DONE_EXECUTING_START, data.startId, res);
...
}
}核心是发送了一个SERVICE_ARGS的message。
2.11:ActivityManagerService.handleMessage:处理不同的message(炸弹)
//frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
public class ActivityManagerService extends IActivityManager.Stub{
final MainHandler mHandler;
final ActiveServices mServices;
final class MainHandler extends Handler {
public MainHandler(Looper looper) {
super(looper, null, true);
}
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case SERVICE_TIMEOUT_MSG: {
//抛出anr
mServices.serviceTimeout((ProcessRecord)msg.obj);
}
break;
case SERVICE_FOREGROUND_TIMEOUT_MSG: {
//抛出anr
mServices.serviceForegroundTimeout((ServiceRecord)msg.obj);
}
break;
case SERVICE_FOREGROUND_CRASH_MSG: {
//引发crash,报错Context.startForegroundService() did not then call Service.startForeground() xxx
mServices.serviceForegroundCrash(
(ProcessRecord) msg.obj, msg.getData().getCharSequence(SERVICE_RECORD_KEY));
}
break;
}
}
}
}2.12:Service.startFroeground:前台Service必须调用,展示通知,解除崩溃炸弹
对于前台Service,必须在Service启动之后手动调用Service.startFroeground,否则会触发上文中的崩溃炸弹:
//frameworks/base/core/java/android/app/Service.java
public abstract class Service extends ContextWrapper {
public final void startForeground(int id, Notification notification) {
try {
mActivityManager.setServiceForeground(
new ComponentName(this, mClassName), mToken, id,
notification, 0, FOREGROUND_SERVICE_TYPE_MANIFEST);
} catch (RemoteException ex) {
}
}
}最终调用到了AMS.setServiceForeground:
//frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
public class ActivityManagerService extends IActivityManager.Stub{
final ActiveServices mServices;
@Override
public void setServiceForeground(ComponentName className, IBinder token,
int id, Notification notification, int flags, int foregroundServiceType) {
synchronized(this) {
mServices.setServiceForegroundLocked(className, token, id, notification, flags,
foregroundServiceType);
}
}
}核心是调用
ActiveServices.setServiceForegroundLocked.
2.13:ActiveServices.setServiceForegroundLocked:发送通知,取消崩溃
//frameworks/base/services/core/java/com/android/server/am/ActiveServices.java
public final class ActiveServices {
public void setServiceForegroundLocked(ComponentName className, IBinder token,
int id, Notification notification, int flags, int foregroundServiceType) {
final int userId = UserHandle.getCallingUserId();
final long origId = Binder.clearCallingIdentity();
try {
ServiceRecord r = findServiceLocked(className, token, userId);
if (r != null) {
setServiceForegroundInnerLocked(r, id, notification, flags, foregroundServiceType);
}
} finally {
Binder.restoreCallingIdentity(origId);
}
}
/**
* @param id Notification ID. Zero === exit foreground state for the given service.
*/
private void setServiceForegroundInnerLocked(final ServiceRecord r, int id,
Notification notification, int flags, int foregroundServiceType) {
//id不可为0
if (id != 0) {
//notification不可为空
if (notification == null) {
throw new IllegalArgumentException("null notification");
}
...
if (r.fgRequired) {
if (DEBUG_SERVICE || DEBUG_BACKGROUND_CHECK) {
Slog.i(TAG, "Service called startForeground() as required: " r);
}
r.fgRequired = false;
r.fgWaiting = false;
alreadyStartedOp = stopProcStatsOp = true;
//移除SERVICE_FOREGROUND_TIMEOUT_MSG消息,取消崩溃
mAm.mHandler.removeMessages(
ActivityManagerService.SERVICE_FOREGROUND_TIMEOUT_MSG, r);
}
}
}
}3:整个Service启动过程中涉及到的跨进程调用
3.1:ContextImpl -→ AMS:调用方进程→system_server进程
- 被调用方法:AMS中的startService()
ActivityManager.getService().startService()
3.2:ActivityThread -→ AMS:service所在进程→system_server进程
- 被调用方法:AMS中的attachApplication()
ActivityManager.getService().attachApplication()
- 拆除炸弹
ActivityManager.getService().serviceDoneExecuting()
3.3: AMS -→ ActivityThread:system_server进程→service所在进程
- 被调用方法:ApplicationThread中的scheduleCreateService()
app.thread.scheduleCreateService()
- 被调用方法:ApplicationThread中的scheduleServiceArgs()
app.threadscheduleServiceArgs()
4:总结
基于上述源码的分析,我们可以将Service的整体启动流程总结为下图:
Service启动流程图
以上就是Android中Service启动的大致原理,如果觉得有收获,欢迎关注点赞~
