bindService的用法
private IMyAidlInterface iMyAidlInterface;
private void bindService() {
Intent intent = new Intent();
intent.setComponent(new ComponentName("com.example.aidlserver", "MyService"));
bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE);
}
private ServiceConnection serviceConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
iMyAidlInterface = IMyAidlInterface.Stub.asInterface(service);
try {
iMyAidlInterface.hi("");
} catch (RemoteException e) {
e.printStackTrace();
}
}
@Override
public void onServiceDisconnected(ComponentName name) {
}
};
bindService的大致流程
bindService涉及哪些参与者
1.客户端进程(请求端) 2.系统进程 3.serviceManager进程 4. 服务端进程
通讯过程是怎样的?
1. bindService时传递的ServiceConnection参数
在绑定服务时调用bindService(Intent service, ServiceConnection conn, int flags),在绑定成功后的ServiceConnection对象里onServiceConnected()将会收到服务端传来的代理对象。所以先从bindService时传入的ServiceConnection对象开始探究,这个ServiceConnection对象如何被保存?如何通过ServiceConnection对象回调服务代理对象?
根据bindService()源码看下:
frameworks\base\core\java\android\app\ContextImpl.java
@Override
public boolean bindService(Intent service, ServiceConnection conn,
int flags) {
warnIfCallingFromSystemProcess();
return bindServiceCommon(service, conn, flags, mMainThread.getHandler(), getUser());
}
接着看下bindServiceCommon():
frameworks\base\core\java\android\app\ContextImpl.java
private boolean bindServiceCommon(Intent service, ServiceConnection conn, int flags, Handler
handler, UserHandle user) {
// Keep this in sync with DevicePolicyManager.bindDeviceAdminServiceAsUser.
IServiceConnection sd;
...
if (mPackageInfo != null) {
//根据请求时传入的ServiceConnection获取IServiceConnection对象
sd = mPackageInfo.getServiceDispatcher(conn, getOuterContext(), handler, flags);
}
...
// IServiceConnection对象传入到ams中,进行bindService
int res = ActivityManager.getService().bindService(mMainThread.getApplicationThread(), getActivityToken(), service,
service.resolveTypeIfNeeded(getContentResolver()), sd, flags, getOpPackageName(), user.getIdentifier());
...
}
接下来再看下 mPackageInfo.getServiceDispatcher(conn, getOuterContext(), handler, flags);
这里怎么根据请求时传入的ServiceConnection获取IServiceConnection对象,这个IServiceConnection对象有什么用处?
frameworks\base\core\java\android\app\LoadedApk.java
public final IServiceConnection getServiceDispatcher(ServiceConnection c,
Context context, Handler handler, int flags) {
synchronized (mServices) {
LoadedApk.ServiceDispatcher sd = null;
// ArrayMap<Context, ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher>> mServices
// mServices中存着当前进程所有请求绑定服务的context和对应的接收服务的派遣对象
ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher> map = mServices.get(context);
//如果当前上下文从未绑定过服务则map为空
if (map != null) {
if (DEBUG) Slog.d(TAG, "Returning existing dispatcher " + sd + " for conn " + c);
// 根据ServiceConnection获取ServiceDispatcher对象;
// ServiceDispatcher用于系统进程返回服务代理给客户端时的派遣
sd = map.get(c);
}
//如果当前ServiceConnection首次传入绑定服务时,map里没有该sd
if (sd == null) {
//新建ServiceDispatcher对象
sd = new ServiceDispatcher(c, context, handler, flags);
if (DEBUG) Slog.d(TAG, "Creating new dispatcher " + sd &