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();
        }
    };

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Android AIDLAndroid Interface Definition Language)是一种Android中用于实现跨进程通信的机制。它允许一个应用程序的进程与另一个应用程序的进程进行交互。 在AIDL中,双向通信可以通过以下步骤实现: 1. 创建AIDL接口:首先,在服务提供方的应用程序中创建一个AIDL接口类,该接口定义了需要两个应用程序之进行通信的方法。 2. 实现AIDL接口:在服务提供方的应用程序中实现AIDL接口。这些方法将用于处理由客户端发起的请求。 3. 绑定Service:在客户端应用程序中,通过绑定Service与提供方建立连接。这可以通过Intent和bindService()方法完成。 4. 获取Service接口:一旦客户端与服务提供方建立了连接,客户端将获得Service的接口。这个接口将通过onServiceConnected()方法返回给客户端。 5. 调用方法:客户端可以使用接口对象来调用服务提供方的方法,从而向服务提供方发送请求。 6. 返回结果:服务提供方在接收到请求后,根据请求的类型进行相应的处理,并将处理结果返回给客户端。 通过以上步骤,双向通信将会在两个应用程序之建立起来。服务提供方可以处理客户端的请求,并将结果返回给客户端。而客户端可以调用服务提供方的方法,并获取所需的数据。 需要注意的是,为了保证AIDL双向通信的正常运行,需要AndroidManifest.xml文件中声明相应的权限和服务。 总结来说,使用Android AIDL可以实现双向通信。服务提供方与客户端通过AIDL接口进行交互,客户端发送请求给服务提供方,并获取处理结果。这种机制可以方便地实现不同应用程序之的数据交换和通信

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值