从AILD与bindService谈Binder进程间通信原理(上)
前言
Android进程间通信可以分为三种方式:Binder机制,文件读写,Socket机制。这篇文章主要就是来谈谈Binder机制实现进程间通信的原理,主要分析AIDL进程间通信和bindService方法涉及的进程间数据传输相关逻辑。
AIDL实现进程间通信:
通过AIDL具体如何实现进程间通信,我推荐阅读以下文章:
Android:学习AIDL,这一篇文章就够了(上)
Android:学习AIDL,这一篇文章就够了(下)
这两篇文章把AIDL进程间通信的具体实现和代码原理进行了详细的讲解。
但是,我看到这里产生了2个疑惑:
1,服务端进程并没有开启一个线程去处理远程服务请求,如何服务?
2,与系统服务的Binder通信方式比较,并没有发现向ServiceManager注册服务和请求服务的过程,如何注册和获取服务?且AIDL中远程数据是如何跨进程传输的
1-答:Android进程本身就支持Binder进程间通信机制。因为安卓进程通过Zygote创建的时候,已经在AppRuntime的onZygoteInit()方法中调用了startThreadPool()方法。
2-答:Binder通信并非必须通过ServiceManager.addService(String name, IBinder service)来向ServiceManager进程注册服务,还可以通过Parcel中的writeStrongBinder方法把JavaBBinder类型Binder实体添加到ServiceManager中;而且并非必须使用ServiceManager.getService(String name)获得BpBinder对象,还可以通过Parcel中的readStrongBinder获取一个BpBinder对象用于请求远程服务。
就以上二个问题详细分析AIDL实现的具体逻辑:
1 Android进程本身就支持Binder进程间通信机制。安卓进程通过Zygote创建的时候,已经在AppRuntime的onZygoteInit()方法中调用了startThreadPool()方法创建了一个用于Binder通信的线程,因此,我们自己创建的远程服务不需要再额外创建一个新的线程去处理远程请求。
具体的android进程启动,推荐查看下面的文章:
Android应用程序进程启动过程的源代码分析
2 结合AIDL实际来说明这个问题
首先,我们看看AIDL实现的关键代码:
1,Binder核心代码:
public static abstract class Stub extends android.os.Binder implements MyAIDL
{
public static MyAIDL asInterface(android.os.IBinder obj)
{
if ((obj==null)) {
return null;
}
android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
if (((iin!=null)&&(iin instanceof MyAIDL))) {
return ((MyAIDL)iin);
}
return new MyAIDL.Stub.Proxy(obj);
}
@Override public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException
{
switch (code)
{
case INTERFACE_TRANSACTION:
{
reply.writeString(DESCRIPTOR);
return true;
}
case TRANSACTION_getValue:
{
data.enforceInterface(DESCRIPTOR);
java.lang.String _result = this.getValue();
reply.writeNoException();
reply.writeString(_result);
return true;
}
}
return super.onTransact(code, data, reply, flags);
}
2,BinderProxy核心代码:
private static class Proxy implements MyAIDL
{
private android.os.IBinder mRemote;
Proxy(android.os.IBinder remote)
{
mRemote = remote;
}
@Override public android.os.IBinder asBinder()
{
return mRemote;
}
@Override public java.lang.String getValue() throws android.os.RemoteException
{
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
java.lang.String _result;
try {
_data.writeInterfaceToken(DESCRIPTOR);
mRemote.transact(Stub.TRANSACTION_getValue, _data, _reply, 0);
_reply.readException();
_result = _reply.readString();
}
finally {
_reply.recycle();
_data.recycle();
}
return _result;
}
}
3,客户端关键代码:
public class MainActivity extends Activity {
MyAIDL aidlMain;
@Override
protected void onCreate(Bundle savedInstanceState) {
…………………………
ServiceConnection mServiceConnection=new ServiceConnection() {
…………………………
@Override
public void onServiceConnected(ComponentName name, IBinder service){
// TODO Auto-generated method stub
aidlMain=AIDL_TESTInterface.Stub.asInterface(service);
}
};
……………………………………
bindService(intent, mServiceConnection, Context.BIND_AUTO_CREATE);
}