Adnroid利用AIDL实现Service间的双向通信

网上相当多关于android利用AIDL实现进程间通信文章,基本上都是activity去bind一个service,然后调用客户端,也就是activity这边调用服务端的方法。但我心里一直有个疑问,这种模式是单向的,如何实现AIDL的双向通信?于是跑了下面的Demo。
大致原理是两个Service,Service1和Service2,Service1bind好Service2后,拿到Service2的Binder对象,在本地转成AIDL对象,然后通过这个AIDL对象再传递一个AIDL对象到Serivce2,传过来的这个AIDL的“根”Stub,就是接口的实现,是在Service1这边,这样Service2通过接口可以调用Service1的方法。
下面是代码:
两个AIDL接口的定义:

// IMyAidlInterface.aidl
package com.acxingyun.servicecomunication;
import com.acxingyun.servicecomunication.IRegistAidl;
// Declare any non-default types here with import statements

//传递AIDL接口到对端,需要在文件开始import这个AIDL文件
interface IMyAidlInterface {
    void registAidl(IRegistAidl aidl);
}


// IRegistAidl.aidl
package com.acxingyun.servicecomunication;

// Declare any non-default types here with import statements

interface IRegistAidl {
    /**
     * Demonstrates some basic types that you can use as parameters
     * and return values in AIDL.
     */
     void func();
}

Service1:

public class MyService1 extends Service {
    private String TAG = getClass().getSimpleName();
    //Service2 AIDL在本地的接口对象
    private IMyAidlInterface service2AIDL = null;
    //本地AIDL接口根对象
    private IRegistAidl service1AIDLStub = new IRegistAidl.Stub() {
        @Override
        public void func() throws RemoteException {
            Log.i(TAG, "service1AIDLStub func...");
        }
    };

    private ServiceConnection serviceConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            Log.i(TAG, "onServiceConnected");
            service2AIDL = IMyAidlInterface.Stub.asInterface(service);

            try {
                //传递本地AIDL根对象到Service2
                service2AIDL.registAidl(service1AIDLStub);
            } catch (RemoteException e) {
                e.printStackTrace();
            }
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {

        }
    };

    public MyService1() {
    }

    @Override
    public IBinder onBind(Intent intent) {
        // TODO: Return the communication channel to the service.

        throw new UnsupportedOperationException("Not yet implemented");
    }

    @Override
    public void onCreate() {
        Log.i(TAG, "onCreate...");
        super.onCreate();

        Intent intent = new Intent(getApplicationContext(), MyService2.class);
        bindService(intent,serviceConnection,BIND_AUTO_CREATE);
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        return super.onStartCommand(intent, flags, startId);
    }
}

Service2:

public class MyService2 extends Service {
    //Serivce1 AIDL在本地的接口对象
    IRegistAidl service1AIDL = null;
    private String TAG = getClass().getSimpleName();
    //本地AIDL根对象
    private IBinder service2AIDLStub = new IMyAidlInterface.Stub() {

        @Override
        public void registAidl(IRegistAidl aidl) throws RemoteException {
            Log.i(TAG, "registAidl");
            //接收Service1的AIDL对象
            service1AIDL = aidl;
            test();
        }
    };

    public MyService2() {
    }

    @Override
    public IBinder onBind(Intent intent) {
        // TODO: Return the communication channel to the service.
        return service2AIDLStub;
    }

    public void test(){
        Log.i(TAG, "test...");
        try {
            //通过Serivice1 AIDL在本地的对象调用Service1方法,实现双向通信
            service1AIDL.func();
        } catch (RemoteException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void onCreate() {
        Log.i(TAG, "oncreate...");
        super.onCreate();
    }
}

结果:

01-18 10:30:51.141 16626-16626/com.acxingyun.servicecomunication I/MyService1: onCreate...
01-18 10:30:51.144 16626-16626/com.acxingyun.servicecomunication I/MyService2: oncreate...
01-18 10:30:51.147 16626-16626/com.acxingyun.servicecomunication I/MyService1: onServiceConnected
01-18 10:30:51.147 16626-16626/com.acxingyun.servicecomunication I/MyService2: registAidl
01-18 10:30:51.147 16626-16626/com.acxingyun.servicecomunication I/MyService2: test...
01-18 10:30:51.147 16626-16626/com.acxingyun.servicecomunication I/MyService1: service1AIDLStub func...

两个Serivce,两个AIDL,每个Serice有个AIDL的根对象和另一个AIDL的接口对象,需要注意的是,Service2要返回一个IBinder类型的对象,所以Service2这边要把AIDL接口类型写为IBinder:

private IBinder service2AIDLStub = new IMyAidlInterface.Stub() {

        @Override
        public void registAidl(IRegistAidl aidl) throws RemoteException {
            Log.i(TAG, "registAidl");
            service1AIDL = aidl;
            test();
        }
    };

不同进程间的双向通信类似。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值