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启动的大致原理,如果觉得有收获,欢迎关注点赞~