Service启动流程源码分析(一):startService
来源:互联网 发布:苹果抹除数据后会怎样 编辑:程序博客网 时间:2024/06/09 19:45
Service启动流程源码分析(一):startService
Service是Android组件中最基本也是最为常见用的四大组件之一,分析Service启动流程源码可以加深对Service的了解。Service一共有两种状态,启动和绑定,本文先分析Service启动的流程,大体上和之前的Activity启动流程类似。
Service启动流程源码分析(二):bindService
启动流程
1.多次调用怎么执行 2.执行的线程 3.startService也有注释 分析一下 所有博客都有这几个问题
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 IActivityManager
public 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 scheduleCreateService(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的serviceDoneExecutingActivityManagerNative.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(一)
- Service启动流程源码分析(一):startService
- Service启动流程-startService
- android Service(一) activity启动Service方式一:startService()
- Service的启动(startService)
- Service启动流程源码分析之bindService(二)
- Kubelet源码分析(一) 启动流程分析
- Android服务启动之StartService源码分析
- Android Service 之启动服务( startService() )
- Service的启动--startService
- Activity启动流程源码分析之入门(一)
- Android wifi源码分析(一) Wifi启动流程
- Elasticsearch源码分析(一)启动流程
- Android Service的启动流程源码分析(8.0)
- Android 中 startService()启动service的过程分析
- Android 5.0 startService的启动流程最全面的分析
- Service 启动流程源码解析
- android startService调用流程(一) (android6.0源码)
- springcloud框架下采用Grpc实现远程过程调用
- null和undefined的区别
- !=EOF的含义和原理
- 正则表达式
- 最小路径和
- Service启动流程源码分析(一):startService
- Caffe实战系列:实现自己Caffe网络层
- 隐式的类类型转换
- R语言-数据框
- 单线程爬虫
- 学习笔记之WEB平台自定义标签库
- HDU 1016
- Css: position float display
- 洛谷 P1726 上白泽慧音