|
|
|
@ -103,6 +103,136 @@ bindServiceLocked(IApplicationThread caller, ...){ |
|
|
|
|
requestServiceBindingLocked(s, b.intent, false); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
``` |
|
|
|
|
|
|
|
|
|
```java |
|
|
|
|
final String bringUpServiceLocked(ServiceRecord r, ...) { |
|
|
|
|
if(r.app != null && r.app.thread != null){ |
|
|
|
|
// 如果 Service 已经启动,就执行 Service#onStartCommand |
|
|
|
|
// 在 bind service 中没啥用 |
|
|
|
|
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); |
|
|
|
|
} |
|
|
|
|
return null; |
|
|
|
|
} |
|
|
|
|
``` |
|
|
|
|
|
|
|
|
|
```java |
|
|
|
|
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 发布它的 binder 句柄给 AMS |
|
|
|
|
requestServiceBindingLocked(r, ...); |
|
|
|
|
// 触发 Service 的 onStartCommand 回调 |
|
|
|
|
sendServiceArgsLocked(r, ...); |
|
|
|
|
} |
|
|
|
|
boolean requestServiceBindingLocked(ServiceRecord r, ...) { |
|
|
|
|
if(r.app == null || r.app.thread == null){ |
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
if((!i.requested||rebind)&&i.apps.size()>0){ |
|
|
|
|
r.app.thread.scheduleBindService(r, rebind, ...); |
|
|
|
|
if(!rebind){ |
|
|
|
|
i.requested = true; |
|
|
|
|
} |
|
|
|
|
i.doRebind = false; |
|
|
|
|
} |
|
|
|
|
return true; |
|
|
|
|
} |
|
|
|
|
// scheduleBindService 的处理过程 |
|
|
|
|
private void handleBindService(BindServiceData data) { |
|
|
|
|
Service s = mService.get(data.token); |
|
|
|
|
if(!data.rebind){ |
|
|
|
|
IBinder binder = s.onBind(data.intent); |
|
|
|
|
ActivityManagerNative.getDefault().publishService(data.token, data.intent, binder); |
|
|
|
|
}else { |
|
|
|
|
s.onRebind(data.intent); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
``` |
|
|
|
|
|
|
|
|
|
```java |
|
|
|
|
// AMS#publishServiceLocked |
|
|
|
|
void publishServiceLocked(ServiceRecord r, Intent intent, IBinder service) { |
|
|
|
|
Intent.FilterComparison filter = new Intent.FilterComparison(intent); |
|
|
|
|
IntentBindRecord b = r.bindings.get(filter); |
|
|
|
|
if(b!=null && !b.received){ |
|
|
|
|
b.binder = service; |
|
|
|
|
b.requested = true; |
|
|
|
|
b.received = true; |
|
|
|
|
for(int conni=r.connections.size()-1;conni>=0;conni--) { |
|
|
|
|
ArrayList<ConnectionRecord> clist = r.connections.valueAt(conni); |
|
|
|
|
for(int i=0;i<clist.size();i++){ |
|
|
|
|
ConnectionRecord c = clist.get(i); |
|
|
|
|
if(!filter.equals(c.binding.intent.intent)){ |
|
|
|
|
continue; |
|
|
|
|
} |
|
|
|
|
c.conn.connected(r.name, service); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
``` |
|
|
|
|
|
|
|
|
|
onRebind 什么时候调用? |
|
|
|
|
|
|
|
|
|
```java |
|
|
|
|
int bindServiceLocked(IApplicationThread caller, IBinder token, ) { |
|
|
|
|
if(s.app!=null&&b.intent.received){ |
|
|
|
|
if(b.intent.apps.size()==1&&b.intent.doRebind){ |
|
|
|
|
requestServiceBindingLocked(s, b.intent, callerFg, true); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
boolean unbindServiceLocked(IServiceConnection connection) { |
|
|
|
|
IBinder binder = connection.asBinder(); |
|
|
|
|
ArrayList<ConnectionRecord> clist = mServiceConnections.get(binder); |
|
|
|
|
while(clist.size()>0){ |
|
|
|
|
ConnectionRecord r = clist.get(0); |
|
|
|
|
removeConnectionLocked(r, null, null); |
|
|
|
|
if(clist.size()>0&&clist.get(0)==r){ |
|
|
|
|
clist.remove(0); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
return true; |
|
|
|
|
} |
|
|
|
|
void removeConnectionLocked(ConnectionRecord c, ...){ |
|
|
|
|
if(s.app!=null&&s.app.thread!=null&&b.intent.apps.size()==0&&b.intent.hasBound){ |
|
|
|
|
b.intent.hasBound = false; |
|
|
|
|
b.intent.doRebind = false; |
|
|
|
|
s.app.thread.scheduleUnbindService(s, b.intent.intent.getIntent()); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
private void handleUnbindService(BindServiceData data) { |
|
|
|
|
Service s = mService.get(data.token); |
|
|
|
|
boolean doRebind = s.onUnbind(data.intent); |
|
|
|
|
if(doRebind){ |
|
|
|
|
ActivityManagerNative.getDefault().unbindFinished(doRebind); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
// AMS#unbindFinishedLocked |
|
|
|
|
void unbindFinishedLocked(ServiceRecord r, Intent intent, boolean doRebind) { |
|
|
|
|
Intent.FilterComparison filter = new Intent.FilterComparison(intent); |
|
|
|
|
IntentBindRecord b = r.bindings.get(filter); |
|
|
|
|
if(b.apps.size()>0&&!inDestorying) { |
|
|
|
|
|
|
|
|
|
}else { |
|
|
|
|
b.doRebind = true; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
``` |
|
|
|
|
|
|
|
|
|