parent
2b214e1b2e
commit
6ffeb936c1
@ -0,0 +1,108 @@ |
||||
--- |
||||
Service 的绑定原理 |
||||
--- |
||||
|
||||
1. 知道 bindService 的用法 |
||||
2. 了解 bindService 的大致流程 |
||||
3. bindService 涉及哪些参与者,通信过程是怎样的? |
||||
|
||||
```java |
||||
IRemoteCaller mCaller; |
||||
|
||||
ServiceConnection mServiceConnection = new ServiceConnection(){ |
||||
@Override |
||||
public void onServiceConnected(ComponentName name, IBinder service) { |
||||
mCaller = IRemoteCaller.Stub.asInterface(service); |
||||
mCaller.call(); |
||||
} |
||||
} |
||||
|
||||
Intent service = new Intent(this, MyService.class); |
||||
bindService(service, mServiceConnection, BIND_AUTO_CREATE); |
||||
``` |
||||
|
||||
Bind Service 总体流程: |
||||
|
||||
![](https://i.loli.net/2020/03/24/F4HYsiel7phDGBw.png) |
||||
|
||||
```java |
||||
@Override |
||||
boolean bindService(Intent service, ServiceConnection conn, int flags) { |
||||
return bindServiceCommon(service, conn, flags, ...); |
||||
} |
||||
boolean bindServiceCommon(Intent service, ServiceConnection conn, ...) { |
||||
IServiceConnection sd; |
||||
// 为 ServiceConnection 接口生成一个 binder 对象,可用于跨进程传递给 AMS |
||||
sd = mPackageInfo.getServiceDispatcher(conn, getOuterContext(), mMainThread.getHandler(), flags); |
||||
ActivityManagerNative.getDefult().bindService(mMainThread.getApplicationThread(), service, sd, ...); |
||||
} |
||||
IServiceConnection getServiceDispatcher(ServiceConnection c, ...) { |
||||
ServiceDispatcher sd = null; |
||||
Map<ServiceConnection, ServiceDispatcher> map = mServices.get(context); |
||||
if(map != null){ |
||||
sd = map.get(c); |
||||
} |
||||
if(sd == null){ |
||||
sd = new ServiceDispatcher(c, context, handler,flags); |
||||
if(map == null){ |
||||
map = new ArrayMap<ServiceConnection, ServiceDispatcher>(); |
||||
mService.put(context, map); |
||||
} |
||||
map.put(c, sd); |
||||
} |
||||
return sd.getIServiceConnection(); |
||||
} |
||||
ServiceDispatcher(ServiceConnection conn, ...){ |
||||
mIServiceConnection = new InnerConnection(this); |
||||
mConnection = conn; |
||||
} |
||||
|
||||
static class InnerConnection extends IServiceConnection.Stub { |
||||
final WeakReference<ServiceDispatcher> mDispatcher; |
||||
public void connected(ComponentName name, IBinder service) { |
||||
LoadedApk.ServiceDispatcher sd = mDispatcher.get(); |
||||
if(sd != null){ |
||||
sd.connected(name, service); |
||||
} |
||||
} |
||||
} |
||||
void connected(){ |
||||
mActivityThread.post(new RunConnection(name, service, 0)); |
||||
} |
||||
|
||||
public void doConnected(ComponentName name, IBinder service) { |
||||
old = mActiveConnections.get(name); |
||||
if(old!=null && old.binder == service){ |
||||
return; |
||||
} |
||||
if(service != null){ |
||||
info = new ConnectionInfo(service); |
||||
mActiveConnections.put(name, info); |
||||
}else{ |
||||
mActiveConnections.remove(name); |
||||
} |
||||
if(old != null){ |
||||
mConnection.onServiceDisconnected(name); |
||||
} |
||||
if(service != null){ |
||||
mConnection.onServiceConnected(name, service); |
||||
} |
||||
} |
||||
``` |
||||
|
||||
```java |
||||
// AMS#bindServiceLocked |
||||
bindServiceLocked(IApplicationThread caller, ...){ |
||||
//... |
||||
if((flag&Context.BIND_AUTO_CREATE)!=0){ |
||||
bringUpServiceLocked(s, ); |
||||
} |
||||
if(s.app != null && b.intent.received){ |
||||
c.conn.connected(s.name, b.intent.binder); |
||||
}else if(!b.intent.requested){ |
||||
requestServiceBindingLocked(s, b.intent, false); |
||||
} |
||||
} |
||||
|
||||
``` |
||||
|
After Width: | Height: | Size: 173 KiB |
Loading…
Reference in new issue