赞
踩
Service
是Android
中的四大组件之一,日常开发中我们经常会使用startService
之类的方法来启动Service
,那这个方法调用的底层原理是什么呢?Android
系统是如何启动起来Service
的呢?本文我们从源码出发,介绍一下Android
中的Service
是如何启动Service的,本文的结构如下:
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
的.
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
.
//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
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。