Service启动流程源码分析(一):startService
2017-10-23 22:07
756 查看
Service启动流程源码分析(一):startService
Service是Android组件中最基本也是最为常见用的四大组件之一,分析Service启动流程源码可以加深对Service的了解。Service一共有两种状态,启动和绑定,本文先分析Service启动的流程,大体上和之前的Activity启动流程类似。Service启动流程源码分析(二):bindService
启动流程
Activity
本文从Activity的startService(Intent service)入手分析Activity的startService(Intent service)代码如下
@Override public ComponentName startService(Intent service) { // mBase在之前Activity启动流程中分析过,是在Activity的attach方法中赋值的,是一个ContextImpl return mBase.startService(service); }
调用ContextImpl的startService(service),代码如下
@Override public ComponentName startService(Intent service) { warnIfCallingFromSystemProcess(); return startServiceCommon(service, mUser); }
调用ContextImpl的startServiceCommon(Intent service, UserHandle user),代码如下
private ComponentName startServiceCommon(Intent service, UserHandle user) { try { // Android 5.0之后不允许隐式启动Service validateServiceIntent(service); // Binder调用ActivityManagerNative.getDefault()启动Service,同Activity的启动 ComponentName cn = ActivityManagerNative.getDefault().startService( mMainThread.getApplicationThread(), service, service.resolveTypeIfNeeded( getContentResolver()), getOpPackageName(), user.getIdentifier()); ... return cn; } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } }
Android 5.0之后不允许隐式启动Service,个人觉得Google是为了安全考虑,限制代码如下
private void validateServiceIntent(Intent service) { // 5.0以上启动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; } else { Log.w(TAG, "Implicit intents with startService are not safe: " + service + " " + Debug.getCallers(2, 3)); } } }
ActivityManagerService
public abstract class ActivityManagerNative extends Binder implements IActivityManagerpublic interface IActivityManager extends IInterface
从中可以看出ActivityManagerNative是一个Binder类,Service的启动已经通过Binder调用转交到系统服务中了。
IActivityManager Binder具体实现是ActivityManagerService,最终调用到ActivityManagerService的startService
调用进入ActivityManagerService的进程
ActivityManagerService的startService(IApplicationThread caller, Intent service,
String resolvedType, String callingPackage, int userId)是一次Binder调用,代码如下
@Override public ComponentName startService(IApplicationThread caller, Intent service, String resolvedType, String callingPackage, int userId) throws TransactionTooLargeException { ... synchronized(this) { ... // mServices是一个ActiveServices ComponentName res = mServices.startServiceLocked(caller, service, resolvedType, callingPid, callingUid, callingPackage, userId); return res; } }
ActiveServices
ActiveServices是AMS中专门抽出来管理Service活动的类,包括启动、绑定等。ActiveServices的startServiceLocked调用了startServiceInnerLocked
startServiceInnerLocked调用了bringUpServiceLocked
bringUpServiceLocked调用了realStartServiceLocked
realStartServiceLocked代码如下
private final void realStartServiceLocked(ServiceRecord r, ProcessRecord app, boolean execInFg) throws RemoteException { ... try { ... // 第一步,主要就是通过app.thread(ApplicationThread)Binder调用scheduleCreateService启动Service app.thread.scheduleCreateService(r, r.serviceInfo, mAm.compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo), app.repProcState); ... } // 第二步,sendServiceArgsLocked调用了ApplicationThread的scheduleServiceArgs方法 sendServiceArgsLocked(r, execInFg, true); ... }
ApplicationThread
IApplicationThread thread;public interface IApplicationThread extends IInterface
public abstract class ApplicationThreadNative extends Binder implements IApplicationThread
ApplicationThreadNative的具体实现是ActivityThread中的ApplicationThread
ApplicationThread实现了许多Activity和Service 启动、暂停等有关的操作
调用进入应用程序的进程
第一步,调用ApplicationThread的scheduleCreateService,是一次Binder调用
public final void scheduleCreat 4000 eService(IBinder token, ServiceInfo info, CompatibilityInfo compatInfo, int processState) { ... // 类似Activity启动,通过mH发送一条CREATE_SERVICE消息 sendMessage(H.CREATE_SERVICE, s); }
mH收到H.CREATE_SERVICE,调用handleCreateService(CreateServiceData data),代码如下
private void handleCreateService(CreateServiceData data) { LoadedApk packageInfo = getPackageInfoNoCheck( data.info.applicationInfo, data.compatInfo); Service service = null; try { // 实例化Service java.lang.ClassLoader cl = packageInfo.getClassLoader(); service = (Service) cl.loadClass(data.info.name).newInstance(); } try { // 创建ContextImpl ContextImpl context = ContextImpl.createAppContext(this, packageInfo); // 尝试创建Application Application app = packageInfo.makeApplication(false, mInstrumentation); // 将之前创建的ContextImpl给service的mBase赋值 service.attach(context, this, data.info.name, data.token, app, ActivityManagerNative.getDefault()); // 调用Service的onCreate方法 service.onCreate(); // 将service对象保存在ActivityThread中 // final ArrayMap<IBinder, Service> mServices = new ArrayMap<>(); mServices.put(data.token, service); try { // 调用AMS的serviceDoneExecuting ActivityManagerNative.getDefault().serviceDoneExecuting( data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0); } ... } }
第二步,调用ApplicationThread的scheduleServiceArgs,是一次Binder调用
scheduleServiceArgs类似scheduleCreateService,通过mH发送H.SERVICE_ARGS,mH收到消息调用handleServiceArgs(ServiceArgsData data),代码如下
private void handleServiceArgs(ServiceArgsData data) { Service s = mServices.get(data.token); if (s != null) { try { if (!data.taskRemoved) { // 调用Service的onStartCommand方法 res = s.onStartCommand(data.args, data.flags, data.startId); } ... } ... }
handleServiceArgs最终调用了Service的onStartCommand方法
总结
流程图待补充Service启动流程源码分析(二):bindService
相关文章推荐
- Service启动流程源码分析之startService(一)
- Android服务启动之StartService源码分析
- Service启动流程源码分析之bindService(二)
- Android 5.0 startService的启动流程最全面的分析
- Android笔记-service启动过程分析:startService源码分析
- Android Service的启动流程源码分析(8.0)
- Activity启动流程源码分析之startActivity启动(三)
- Android 8.0系统源码分析--startService启动过程源码分析
- Android笔记-service启动过程分析:bindService源码分析、startService和bindService区别
- Android源码解析之新进程中启动自定义服务过程(startService)的原理分析
- Android 5.0 Camera系统源码分析(1):CameraService启动流程
- Android 5.0 Camera系统源码分析(1):CameraService启动流程
- Android服务启动之StartService源码分析
- Android 5.0 Camera系统源码分析(1):CameraService启动流程
- ARM Linux启动流程分析——start_kernel前启动阶段(汇编部分)
- 【源码分析】Android系统启动流程.
- spark 1.6.0 core源码分析4 worker启动流程
- Quartz源码——scheduler.start()启动源码分析(二)
- Activity启动流程源码分析之Launcher启动(二)
- Android启动流程分析(十) action的执行和service的启动