parent
							
								
									740ed05dda
								
							
						
					
					
						commit
						2b214e1b2e
					
				| @ -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<mPendingService.size();i++) { | ||||
|         sr = mPendingService.get(i); | ||||
|         //... | ||||
|         mPendingServices.remove(i--); | ||||
|         realStartServiceLocked(sr, proc, ...); | ||||
|     } | ||||
| } | ||||
| void realStartServiceLocked(ServiceRecord r, ProcessRecord app, ...) { | ||||
|     r.app = app; | ||||
|     // scheduleCreateService: 向应用端发起 IPC 调用 | ||||
|     // 应用端收到之后就会去创建 Service,并执行 onCreate 回调 | ||||
|     // r: class ServiceRecord extends Binder{} | ||||
|     app.thread.scheduleCreateService(r, r.serviceInfo, ...); | ||||
|     // 触发 Service 的 onStartCommand 回调 | ||||
|     sendServiceArgsLocked(r, ...); | ||||
| } | ||||
| 
 | ||||
| // 应用端处理 CreateService 请求,运行在主线程 | ||||
| private void handleCreateService(CreateServiceData data) { | ||||
|     LoadedApk = packageInfo = getPackageInfoNoCheck(...); | ||||
|     Service service = (Service)cl.loadClass(data.info.name).newInstance(); | ||||
|      | ||||
|     ContextImpl context = ContextImpl.createAppContext(this, ...); | ||||
|      | ||||
|     Application app = packageInfo.makeApplication(false, ...); | ||||
|     service.attach(context, this, ...); | ||||
|     service.onCreate(); | ||||
|     // mService: ArrayMap<IBinder, Service>,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); | ||||
|     } | ||||
| } | ||||
| ``` | ||||
| 
 | ||||
| **总结** | ||||
| 
 | ||||
|  | ||||
| 
 | ||||
|  | ||||
| 
 | ||||
| 绑定服务: | ||||
| 
 | ||||
| ```java | ||||
| int bindServiceLocked(IApplicationThread caller, ...) { | ||||
| 	//... | ||||
| 	if((flags & Context.BIND_AUTO_CREATE)!=0){ | ||||
| 		bringUpServiceLocked(s, ...); | ||||
| 	} | ||||
| } | ||||
| ``` | ||||
| 
 | ||||
| BindService 并不会触发 onStartCommand,因为 bind service 它没有给 ServiceRecord 加到 pendingStarts 队列里面。 | ||||
| After Width: | Height: | Size: 266 KiB | 
| After Width: | Height: | Size: 336 KiB | 
					Loading…
					
					
				
		Reference in new issue