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); |
||||||
|
} |
||||||
|
} |
||||||
|
``` |
||||||
|
|
||||||
|
**总结** |
||||||
|
|
||||||
|
![](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 队列里面。 |
After Width: | Height: | Size: 266 KiB |
After Width: | Height: | Size: 336 KiB |
Loading…
Reference in new issue