从AILD与bindService谈Binder进程间通信原理(上)

本文上半部分详细分析了Android中AIDL实现Binder进程间通信的原理,探讨了服务端如何处理远程请求,以及无需通过ServiceManager注册和获取服务的原因。内容涵盖客户端启动远程服务、Parcel数据打包、Binder对象转换、内核中BinderDriver的角色,以及服务端如何接收和处理请求的过程。
摘要由CSDN通过智能技术生成

从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);
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值