分析源码前先布置例子代码
一. 服务端 进程:
- 定义一个 AIDL 接口
interface UserAidl { String getUserName(); String getPassword(); }
- 创建一个服务,让客户端绑定这个服务然后获取 服务端返回的 IBinder,也就是 mBinder
public class MessageService extends Service { private final UserAidl.Stub mBinder = new UserAidl.Stub() { @Override public String getUserName() throws RemoteException { return "ytempest"; } @Override public String getPassword() throws RemoteException { return "1234567"; } }; @Override public IBinder onBind(Intent intent) { return mBinder; } }
- 在 AndroidManifest.xml 配置这个服务,然后添加一个 action,让客户端可以隐式绑定这个服务端;启动这个服务,服务端的布置到这里
<service android:name=".service.MessageService" > <intent-filter> <action android:name="com.ytempest.aidl.useraidl" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> </service>
二. 客户端 进程
- 定义一个和 服务端一样的 AIDL 接口(注意:这个AIDL接口要和服务端的AIDL包名一直,不然会GG)
interface UserAidl { String getUserName(); String getPassword(); }
- 创建 绑定服务端服务需要的 ServiceConnection
private UserAidl mUserAidl; private ServiceConnection mServiceConn = new ServiceConnection() { // 绑定服务成功的时候调用 @Override public void onServiceConnected(ComponentName name, IBinder service) { // 这个 IBinder 就是服务端 MessageService服务中 onBind() 方法返回的 mBinder mUserAidl = UserAidl.Stub.asInterface(service); } // 断开绑定服务的时候调用 @Override public void onServiceDisconnected(ComponentName name) { mUserAidl = null; } };
- 然后绑定 服务端的服务以获取 服务端的 IBinder
Intent intent = new Intent(); // 指向有该 action 的服务 intent.setAction("com.ytempest.aidl.useraidl"); // 设置 目的App包 intent.setPackage("com.ytempest.aidltest"); boolean bind = bindService(intent, mServiceConn, Context.BIND_AUTO_CREATE);
- 获取 服务端服务返回的数据
if (mUserAidl != null) { String userName = null; String password = null; try { userName = mUserAidl.getUserName(); password = mUserAidl.getPassword(); } catch (RemoteException e) { e.printStackTrace(); } }
进程布置完毕,现在开始看源码,看源码的时候记住
- 客户端的是怎么绑定服务端的服务的
- 客户端的 ServiceConnection 对象传到哪里去了
- 在哪里获取到了服务端的 IBinder的
- 绑定服务端的服务后,mServiceConn 中的 onServiceConnected 方法是就如何获取到 服务端返回的 mBinder的
1. 点击 MainActivity 的 bindService() 方法最终找到的是 ContextWrapper 类的抽象方法,查看这个类的实现类 ContextImpl 类
★ ContextImpl 类 bindService() 方法源码
@Override
public boolean bindService(Intent service, ServiceConnection conn,
int flags) {
warnIfCallingFromSystemProcess();
return bindServiceCommon(service, conn, flags, Process.myUserHandle());
}
★ ContextImpl 类 bindServiceCommon() 方法源码
private boolean bindServiceCommon(Intent service, ServiceConnection conn, int flags,
UserHandle user) {
...
IServiceConnection sd;
if (mPackageInfo != null) {
// mPackageInfo 是 LoadedApk对象,
sd = mPackageInfo.getServiceDispatcher(conn, getOuterContext(),
mMainThread.getHandler(), flags);
}
try {
...
int res = ActivityManagerNative.getDefault().bindService(
mMainThread.getApplicationThread(), getActivityToken(),
service, service.resolveTypeIfNeeded(getContentResolver()),
sd, flags, user.getIdentifier());
...
} catch (RemoteException e) {
return false;
}
}
问题①:mPackageInfo.getServiceDispatcher 方法做了什么?返回的是什么?
问题②:ActivityManagerNative.getDefault() 方法返回的是什么?
解答①:
mPackageInfo是一个 LoadedApk类,调用 getServiceDispatcher() 方法,在这个方法中会创建一个 ServiceDispatcher对象,然后将 ServiceConnection 对象传进去了,最后调用这个类的 getIServiceConnection() 方法
★ LoadedApk 类 getServiceDispatcher() 方法的源代码如下:
public final IServiceConnection getServiceDispatcher(ServiceConnection c,
Context context, Handler handler, int flags) {
synchronized (mServices) {
ServiceDispatcher sd = null;
ArrayMap<ServiceConnection, ServiceDispatcher> map = mServices.get(context);
if (map != null) {
sd = map.get(c);
}
if (sd == null) {
// 创建了一个 ServiceDispatcher对象,并将 ServiceConnection对象传进去了
sd = new ServiceDispatcher(c, context, handler, flags);
if (map == null) {
map = new ArrayMap<ServiceConnection, ServiceDispatcher>();
mServices.put(context, map);
}
map.put(c, sd);
} else {
sd.validate(context, handler);
}
return sd.getIServiceConnection();
}
}
这里的问题就有:
- 创建了一个 ServiceDispatcher对象做了什么
- 将 ServiceConnection 对象传到了 ServiceDispatcher类的 mConnection 中
- 用一个实现了 IServiceConnection 这一个 AIDL接口的 InnerConnection 对象 实例化了 mIServiceConnection 对象,而这个对象经过一系列参数传递,最终会传递到 ActiveServices 类中的 bindServiceLocked() 方法中进行封装
- getIServiceConnection() 方法返回了什么
返回一个 IServiceConnection 对象(InnerConnection 类向上转型得到)
(1.1) 由 ServiceDispatcher 类的构造方法可以知道,ServiceConnection 对象最终是传到了 ServiceDispatcher类的 mConnection中
★ LoadedApk 类的 内部类 ServiceDispatcher 的构造方法源码如下:
ServiceDispatcher(ServiceConnection conn,
Context context, Handler activityThread, int flags) {
mIServiceConnection = new InnerConnection(this);
// mConnection 也是一个 ServiceConnection 对象
// 这个ServiceConnection对象会在 绑定成功(或失败时)调用其两个回调方法
mConnection = conn;
mContext = context;
mActivityThread = activityThread;
mLocation = new ServiceConnectionLeaked(null);
mLocation.fillInStackTrace();
mFlags = flags;
}
(1.2)由上可知道 创建了一个 InnerConnection 对象,并将 this 传进去保存在 mDispatcher 中,这个对象在 connect() 方法中会使用。由源码可以知道 InnerConnection 类继承了 IServiceConnection 这一个 AIDL接口,实现了这个接口的 connect() 方法
★ LoadedApk类 中的 内部类ServiceDispatcher 中的 内部类InnerConnection 源码如下:
private static class InnerConnection extends IServiceConnection.Stub {
final WeakReference<ServiceDispatcher> mDispatcher;
InnerConnection(ServiceDispatcher sd) {
mDispatcher = new WeakReference<ServiceDispatcher>(sd);
}
public void connected(ComponentName name, IBinder service) throws RemoteException {
ServiceDispatcher sd = mDispatcher.get();
if (sd != null) {
sd.connected(name, service);
}
}
}
解答②:
(1.1)sDefault 是一个单例,get() 方法返回一个实例
★ ActivityManagerNative 类中的 getDefault() 方法源码
static public IActivityManager getDefault() {
return gDefault.get();
}
(1.2 )可以看到 sDefault是一个单例,Singleton就是一个单例模板,通过实现 create() 方法,在这个方法中实例化单例,然后返回给 mInstance;这里通过 asInterface() 方法创建了一个对象,然后返回给了 mIstance
private static final Singleton<IActivityManager> gDefault = new Singleton<IActivityManager>() {
protected IActivityManager create() {
IBinder b = ServiceManager.getService("activity");
if (false) {
Log.v("ActivityManager", "default service binder = " + b);
}
IActivityManager am = asInterface(b);
if (false) {
Log.v("ActivityManager", "default service = " + am);
}
return am;
}
};
public abstract class Singleton<T> {
private T mInstance;
protected abstract T create();
public final T get() {
synchronized (this) {
if (mInstance == null) {
mInstance = create();
}
return mInstance;
}
}
}
(1.3)get() 方法返回的是一个 IActivityManager 的接口,那我们要找到它的实现类,最终找到了 ActivityManagerService
解答:
get() 方法返回的是一个 ActivityManagerService 对象,也就是说 getDefault() 方法返回的是一个 ActivityManagerService 对象
2. ActivityManagerService 类中的 bindService() 方法没有做什么
★ ActivityManagerService 类中的 bindService() 方法源码:
public int bindService(IApplicationThread caller, IBinder token,
Intent service, String resolvedType,
IServiceConnection connection, int flags, int userId) {
enforceNotIsolatedCaller("bindService");
....
synchronized(this) {
return mServices.bindServiceLocked(caller, token, service, resolvedType,
connection, flags, userId);
}
}
3. mServices 是 ActiveServices对象, ActiveServices 类中的 bindServiceLocked() 方法做了什么?
解答:
- 先获取了一个 ServiceRecord对象;
- 然后实例化了 一个 ConnectionRecord 对象,将 IServiceConnection 传到了ConnectionRecord 对象中的 conn 中(这个时候后面的关键);
- 获取客户端的 IBinder
- 从 ServiceRecord对象中的 connections (ArrayMap<IBinder, ArrayList<ConnectionRecord>>)中根据 客户端的IBinder 获取ConnectionRecord集合,如果ConnectionRecord集合为空,则将客户端的 IBinder缓存到 connections中;
- 将ConnectionRecord 对象添加 ConnectionRecord集合(也就是ArrayMap<IBinder, ArrayList<ConnectionRecord>>中的 ArrayList)中去
★ ActiveServices 类中的 bindServiceLocked() 方法源码如下:
int bindServiceLocked(IApplicationThread caller, IBinder token,
Intent service, String resolvedType,
IServiceConnection connection, int flags, int userId) {
...
ServiceRecord s = res.record;
try {
...
AppBindRecord b = s.retrieveAppBindingLocked(service, callerApp);
ConnectionRecord c = new ConnectionRecord(b, activity,
connection, flags, clientLabel, clientIntent);
// 将我们客户端的 ServiceConnection(只是经过一系列封装
// 成了 InnerConnection而已,本质不变),转换成IBinder
IBinder binder = connection.asBinder();
// 重点重点:这里从 s的 connections中根据我们获取 ConnectionRecord集合,但是第一次肯定获取不到,因为没有缓存
ArrayList<ConnectionRecord> clist = s.connections.get(binder);
if (clist == null) {
// 当 clist为空,则实例化一个ConnectionRecord集合,然后
// 将我们客户端的IBinder作为key,ConnectionRecord集合作为值缓存到 ServiceRecord中的 connections(Map)中
clist = new ArrayList<ConnectionRecord>();
s.connections.put(binder, clist);
}
clist.add(c);
b.connections.add(c);
if (activity != null) {
if (activity.connections == null) {
activity.connections = new HashSet<ConnectionRecord>();
}
activity.connections.add(c);
}
b.client.connections.add(c);
if ((c.flags&Context.BIND_ABOVE_CLIENT) != 0) {
b.client.hasAboveClient = true;
}
if (s.app != null) {
updateServiceClientActivitiesLocked(s.app, c, true);
}
clist = mServiceConnections.get(binder);
if (clist == null) {
clist = new ArrayList<ConnectionRecord>();
mServiceConnections.put(binder, clist);
}
clist.add(c);
if ((flags&Context.BIND_AUTO_CREATE) != 0) {
s.lastActivity = SystemClock.uptimeMillis();
if (bringUpServiceLocked(s, service.getFlags(), callerFg, false) != null) {
return 0;
}
}
}
....
if (s.app != null && b.intent.received) {
try {
c.conn.connected(s.name, b.intent.binder);
} catch (Exception e) {
...
}
if (b.intent.apps.size() == 1 && b.intent.doRebind) {
requestServiceBindingLocked(s, b.intent, callerFg, true);
}
} else if (!b.intent.requested) {
requestServiceBindingLocked(s, b.intent, callerFg, false);
}
}
第 2 步详解 --> 源码:
ConnectionRecord(AppBindRecord _binding, ActivityRecord _activity,
IServiceConnection _conn, int _flags,
int _clientLabel, PendingIntent _clientIntent) {
binding = _binding;
activity = _activity;
conn = _conn;
flags = _flags;
clientLabel = _clientLabel;
clientIntent = _clientIntent;
}
4. ActiveServices 类中的 bindServiceLocked() 方法会调用 requestServiceBindingLocked() 方法:
★ ActiveServices 类的 requestServiceBindingLocked() 方法的源码如下:
private final boolean requestServiceBindingLocked(ServiceRecord r,
IntentBindRecord i, boolean execInFg, boolean rebind) {
....
if ((!i.requested || rebind) && i.apps.size() > 0) {
try {
bumpServiceExecutingLocked(r, execInFg, "bind");
r.app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_SERVICE);
r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind,
r.app.repProcState);
...
} catch (RemoteException e) {
if (DEBUG_SERVICE) Slog.v(TAG, "Crashed while binding " + r);
return false;
}
}
return true;
}
分析:
r:ServiceRecord 类
app: ProcessRecord 对象
thread: IApplicationThread 接口对象
那么要找到 scheduleBindService() 方法是谁调用的 就要找到 IApplicationThread 接口的实现类,我们找到了 ApplicationThreadNative 类,我们要找到这个类的实现类,这个实现类就是 ActivityThread 类的内部类 ApplicationThread 类
public abstract class ApplicationThreadNative extends Binder
implements IApplicationThread
private class ApplicationThread extends ApplicationThreadNative {
5. 最终会调用到 ActivityThread 的内部类 ApplicationThread 中的 scheduleBindService() 方法,这个方法会安排连接服务端的服务
★ ActivityThread 类的内部类 ApplicationThread 类的 scheduleBindService() 方法的源码
// 将传过来的第一个 ServiceRecord对象 向上转型为 IBinder
// 由此可以知道我们客户端的 ServiceConnection 经过一系列的封装,最终会封装成一个 IBinder对象,然后用于与服务端进程间通信
public final void scheduleBindService(IBinder token, Intent intent,
boolean rebind, int processState) {
updateProcessState(processState, false);
// 存储和 客户端的IBinder 和 intent
BindServiceData s = new BindServiceData();
// 将 IBinder 对象存到 token中
s.token = token;
s.intent = intent;
s.rebind = rebind;
....
sendMessage(H.BIND_SERVICE, s);
}
分析:
这里会发送 消息 给 H(H 继承了 Handler类,H.BIND_SERVICE 是该类的一个静态常量)进行处理,那么找到 这个 H,在 handleMessage() 方法中对 发送过来的 s对象(BindServiceData对象)进行了处理
case BIND_SERVICE:
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceBind");
handleBindService((BindServiceData)msg.obj);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
break;
6. 通信的交接点:就是在 handleBindService() 方法中获取到服务端的IBinder,然后返回给客户端
★ ActivityThread 类的内部类 H 中的 handleBindService() 方法源码如下:
private void handleBindService(BindServiceData data) {
// 这个根据我们的客户端的IBinder获取我们绑定的 service,也就是 MessageService
Service s = mServices.get(data.token);
....
if (s != null) {
try {
data.intent.setExtrasClassLoader(s.getClassLoader());
data.intent.prepareToEnterProcess();
try {
if (!data.rebind) {
// 这里就调用了MessageService服务的 onBind() 方法获取服务返回的IBinder
IBinder binder = s.onBind(data.intent);
// 这里就会将从 MessageService 获取的 IBinder公开出去,然后其他进程能够获取到
ActivityManagerNative.getDefault().publishService(
data.token, data.intent, binder);
} else {
s.onRebind(data.intent);
ActivityManagerNative.getDefault().serviceDoneExecuting(
data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);
}
ensureJitEnabled();
} catch (RemoteException ex) {
}
}...
}
}
7. 由第 1 点分析可以知道 ActivityManagerNative.getDefault() 方法返回的是一个 ActivityManagerService 对象,查看该类的 publishService() 方法
★ ActivityManagerService 类的 publishService() 方法源码如下:
public void publishService(IBinder token, Intent intent, IBinder service) {
....
synchronized(this) {
if (!(token instanceof ServiceRecord)) {
throw new IllegalArgumentException("Invalid service token");
}
mServices.publishServiceLocked((ServiceRecord)token, intent, service);
}
}
8. mServices 是 ActivityServices 类,在调用 publishServiceLocked() 方法前将 我们客户端的 IBinder 转型为了 ServiceRecord类了(重点)
★ ActivityServices 类的 publishServiceLocked() 方法源码如下:
void publishServiceLocked(ServiceRecord r, Intent intent, IBinder service) {
try {
if (r != null) {
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--) {
// 在这里获取我们文章第 3 步存储到 ServiceRecord中 connections中的 ConnectionRecord集合
ArrayList<ConnectionRecord> clist = r.connections.valueAt(conni);
for (int i=0; i<clist.size(); i++) {
// 获取封装了 IServiceConnection的 ConnectionRecord对象
ConnectionRecord c = clist.get(i);
if (!filter.equals(c.binding.intent.intent)) {
if (DEBUG_SERVICE) Slog.v(
TAG, "Not publishing to: " + c);
if (DEBUG_SERVICE) Slog.v(
TAG, "Bound intent: " + c.binding.intent.intent);
if (DEBUG_SERVICE) Slog.v(
TAG, "Published intent: " + intent);
continue;
}
if (DEBUG_SERVICE) Slog.v(TAG, "Publishing to: " + c);
try {
// c:ConnectionRecord对象
// conn:ConnectionRecord对象中的 IServiceConnection接口对象(这个
// 对象我们在第 3 步把我们客户端的IServiceConnection传进去了)
// connected() 方法:这个方法其实就会调用我们第 1 步创建的 InnerConnection对象中的 connected()方法
// 参数:service是服务端返回的 IBinder
c.conn.connected(r.name, service);
} catch (Exception e) {
....
}
}
}
}
serviceDoneExecutingLocked(r, mDestroyingServices.contains(r), false);
}
} finally {
Binder.restoreCallingIdentity(origId);
}
}
9. c.conn.connected() 方法会调用 InnerConnection 内部类的 connected() 方法
★ LoadedApk类 中的 内部类ServiceDispatcher 中的 内部类InnerConnection 的 connected() 方法源码如下:
public void connected(ComponentName name, IBinder service) throws RemoteException {
ServiceDispatcher sd = mDispatcher.get();
if (sd != null) {
// sd 是一个ServiceDispatcher(外部类)对象
sd.connected(name, service);
}
}
10. 最终 ServiceDispatcher 类中的 connected() 方法会调用 本类的 doConnected() 方法
public void connected(ComponentName name, IBinder service) {
if (mActivityThread != null) {
mActivityThread.post(new RunConnection(name, service, 0));
} else {
doConnected(name, service);
}
}
public void doConnected(ComponentName name, IBinder service) {
ConnectionInfo old;
ConnectionInfo info;
synchronized (this) {
if (mForgotten) {
// We unbound before receiving the connection; ignore
// any connection received.
return;
}
old = mActiveConnections.get(name);
if (old != null && old.binder == service) {
// Huh, already have this one. Oh well!
return;
}
if (service != null) {
// A new service is being connected... set it all up.
mDied = false;
info = new ConnectionInfo();
info.binder = service;
info.deathMonitor = new DeathMonitor(name, service);
try {
service.linkToDeath(info.deathMonitor, 0);
mActiveConnections.put(name, info);
} catch (RemoteException e) {
// This service was dead before we got it... just
// don't do anything with it.
mActiveConnections.remove(name);
return;
}
} else {
// The named service is being disconnected... clean up.
mActiveConnections.remove(name);
}
if (old != null) {
old.binder.unlinkToDeath(old.deathMonitor, 0);
}
}
// 如果是一个旧服务将会被断开绑定
if (old != null) {
// 这个 mConnection对象就是我们客户端绑定服务传进来的 ServiceConnection
mConnection.onServiceDisconnected(name);
}
// 如果客户端绑定了一个新的 service则会被执行这个方法
if (service != null) {
mConnection.onServiceConnected(name, service);
}
}