Activity绑定Service时ServiceConnection回调onServiceConnected传过来的IBinder对象,为什么相同进程下是Binder对象,不同进程下是BinderProxy对象。
private ServiceConnection mConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
Log.d(TAG, "IBinder.class.Name : " + service.getClass().getName());
mService = new Messenger(service);
Message msg = Message.obtain();
Bundle data = new Bundle();
String msgString = "hello ,this is client.";
data.putString("msg", msgString);
msg.setData(data);
msg.replyTo = clientHandler;
try {
mService.send(msg);
} catch (RemoteException e) {
e.printStackTrace();
}
}
@Override
public void onServiceDisconnected(ComponentName name) {
}
};
首先android的进程间通信采用的是IPC机制,IPC的主角就是Binder,整个通信机制在设计上是采用了代理模式来实现。
比如:A(客户端)进程要调用B(服务)进程的一个方法funcB(),
这个时候A并不能直接去访问B中的方法(出于数据保护,进程间是不允许直接通信的,IPC利用了共享内存来实现通信的)。
IPC的大致思路是:
A将这个请求委托给客户端的Binder代理,
进而将请求转给BinderDriver,
再将请求给服务端的Binder代理,
最后通过Binder代理调用B中的funcB()。
如果不去考虑中间的过程,客户端调用远程服务(跨进程)的时候,都是获得一个远程服务在本地的代理BinderProxy对象。
通过该对象实现RPC的调用。
Android技术内幕.系统卷.pdf
ANDROID框架揭秘.pdf
这两篇有对源码做详细的说明
之前我也仔细的去看过AIDl的使用,了解了绑定服务的过程,被你这么一问我又重新看到了一遍...
首先我要说我现在还没办法给你完整的分析整个的流程,因为我不懂c,而且我也没有完整的Android系统源码,但是我可以帮你分析一下:
首先Android系统多个层级,除了你想要知道的FrameWork框架层,还有驱动层,驱动层是由c实现的,
例如进程的创建,各种服务的启动(例如控制音量或者是亮度,最终调用的是都是c)。
所以跨进行通信(AIDl),必然会调用驱动层的东西。
(创建进程的开销很大,例如把WebActivity设置到新进程中,第一次会很慢)
你可以先看这个篇博客,他分析了bindService整个流程:
http://blog.csdn.net/zhangyongfeiyong/article/details/51953300
但是注意里面有些方法抛出了TransactionTooLargeException异常,这个异常会在跨进程通信的对象内存过大抛出(例如我们的方法参数和返回值),
也就是说这个地方有可能在什么条件下,会去调用c的代码,我猜测很有可能是在这个过程中,把Binder转化成了BinderProxy。
接下来再看这个,看看里面整理的c的代码,虽然可能是看不懂,但是你会看到Binder和BinderProxy,里面有判断具体要使用哪一个。
http://xxw8393.blog.163.com/blog/static/372568342009828101455182/
所以你想要知道他俩具体转换的地方,我猜测是在c代码的部分,我也只能帮你到这里了,如果你有了新的发现,一定要告诉我。