diff --git a/blogs/Android/Framework/Interview/其他应用组件相关/Service 的启动原理.md b/blogs/Android/Framework/Interview/其他应用组件相关/Service 的启动原理.md new file mode 100644 index 0000000..0407c87 --- /dev/null +++ b/blogs/Android/Framework/Interview/其他应用组件相关/Service 的启动原理.md @@ -0,0 +1,136 @@ +--- +Service 的启动原理 +--- + +1. Service 启动有哪几种方式? +2. Service 启动过程中主要流程有哪些? +3. Service 启动过程涉及哪些参与者,通信过程是怎样的? + +```java +@Override +public ComponentName startService(Intent service) { + return startServiceCommon(service, mUser); +} +``` + +```java +ComponentName startServiceCommon(Intent service, ...) { + ComponentName cn = ActivityManagerNative.getDefault().startService(mMainThread.getApplicationThread(), service, ...); + return cn; +} +``` + +```java +// ASM#startService +ComponentName startService(IApplicationThread caller, Intent service, ...) { + ComponentName res = mService.startServiceLocked(caller, service, ...); + return res; +} +ComponentName startServiceLocked(Intent service, ...){ + ServiceLookupResult res = retrieveServiceLocked(service, ...); + ServiceRecord r = res.record; + //... + r.pendingStarts.add(new ServiceRecord.StartItem(r, ...)); + return startServiceInnerLocked(smap, service, r, ...); +} +ComponentName startServiceInnerLocked(ServiceMap smap, Intent service, ...){ + bringUpServiceLocked(r, service.getFlags(), callerFg, false); +} +final String bringUpServiceLocked(ServiceRecord r, ...) { + if(r.app != null && r.app.thread != null){ + // 如果 Service 已经启动,就执行 Service#onStartCommand + sendServiceArgsLocked(r, ...); + return null; + } + ProcessRecord app = mAm.getProcessRecordLocked(procName, ...); + if(app != null && app.thread != null) { + realStartServiceLocked(r, app, execlnFg); + return null; + } + if(app == null){ + app = mAm.startProcessLocked(procName, ...); + } + if(!mPendingService.contains(r)){ + mPendingService.add(r); + } +} + +``` + +```java +//ASM#attachApplicationLocked +boolean attachApplicationLocked(IApplicationThread thread, ...) { + // 处理 Pending 的 Service + mService.attachApplicationLocked(app, processName); + return true; +} +boolean attachApplicationLocked(ProcessRecord proc, ...) { + for(int i=0;i,key: ServiceRecord + mService.put(data.token, service); +} + +private final void sendServiceArgsLocked(ServiceRecord r, ){ + while(r.pendingStarts.size() > 0){ + StartItem si = r.pendingStarts.remove(0); + // 调到应用端 + r.app.thread.scheduleServiceArgs(r, ...); + } +} +public final void scheduleServiceArgs(IBinder token, ...) { + ServiceArgsData s = new ServiceArgsData(); + //... + sendMessage(H.SERVICE_ARGS, s); +} +private void handleServiceArgs(ServiceArgsData data) { + Service s = mService.get(data, token); + if(s != null){ + s.onStartCommand(data.args, data.flags, data.startId); + } +} +``` + +**总结** + +![](https://i.loli.net/2020/03/24/A6pSmv2zoZMGPnq.png) + +![](https://i.loli.net/2020/03/24/SGLOXC9IHlzBcop.png) + +绑定服务: + +```java +int bindServiceLocked(IApplicationThread caller, ...) { + //... + if((flags & Context.BIND_AUTO_CREATE)!=0){ + bringUpServiceLocked(s, ...); + } +} +``` + +BindService 并不会触发 onStartCommand,因为 bind service 它没有给 ServiceRecord 加到 pendingStarts 队列里面。 \ No newline at end of file diff --git a/images/Android/Framework/Interview/Service 启动流程 - 2.png b/images/Android/Framework/Interview/Service 启动流程 - 2.png new file mode 100644 index 0000000..f34f81f Binary files /dev/null and b/images/Android/Framework/Interview/Service 启动流程 - 2.png differ diff --git a/images/Android/Framework/Interview/Service 启动流程.png b/images/Android/Framework/Interview/Service 启动流程.png new file mode 100644 index 0000000..f29a014 Binary files /dev/null and b/images/Android/Framework/Interview/Service 启动流程.png differ