使用AIDL完成一次简单的Android进程间通信

AIDL(Android Interface Definition Language):安卓接口描述语言。通常我们使用它来帮助我们完成进程间的通信。程序中的数据交换和通信其实都是内存之间的调用来完成的,但是不同的进程之间是不能访问相互之间的内存的,AIDL通过binder机制实现一条管道,客户端和服务端都去实现它,然后利用这个管道相互通信。类似于线程之间共享进程的内存来实现通信,进程则是通过将数据拆分成系统可识别的单元从而进行通信。

一.实现Service的服务端暴露接口进行通信。

要实现进程间的通信,首先作为服务端的应用进程要实现和客户端一样的接口并启动起来,等待客户端的接入。首先是AIDL文件的编写,这两个文件在各自的程序中,放置的包名要一样,程序的应用包名不能一样,否则会冲突,但是AIDL文件的包名要一样。
package com.example.aidlclient;

interface TestPrint{
    void print();
}
以上就是整个AIDL文件的代码,一个包的声明和一个接口的定义,注意这个接口是不能添加public和private这些权限修饰词的。这个AIDL文件的名字是TestPrint.aidl,保存之后将在gen文件夹中对应的目录下自动生成java类。接下来就是Service类的编写,提供接口方法的。
public class MyService extends Service {

    @Override
    public void onCreate() {
        super.onCreate();
        Log.i("com.example.androidserver", "service create success") ;
    }
    @Override
    public IBinder onBind(Intent arg0) {
        return new MyBinder();
    }

    class MyBinder extends TestPrint.Stub {

        @Override
        public void print() throws RemoteException {
            Log.i("com.example.androidserver", "return mybinder") ;
        }

    }
}
这个Service中最重要的就是onBind方法的返回了,客户端连接服务之后拿到这个binder对象进行其他操作,可以看到这个binder对象是继承自TestPrint.Stub类的,这个是AIDL文件自动生成的一个类,这个继承了binder接口,实现了TestPrint里面的接口,所以这个对象可以做onBind方法的返回值,又可以在客户端调用这个已经实现了TestPrint里面接口的方法。接下来就是客户端连接服务端了。

二.客户端:

在客户端里面可以创建一个跟服务端一样的包,并且把服务端里面的AIDL文件拷到客户端里面,客户端也将自动生成一份java类文件,在gen目录下,这时候我们只要启动服务端进程,客户端开启服务连接服务端的service:
class MyServiceConnection implements ServiceConnection {
        public void onServiceConnected(ComponentName name, IBinder binder) {
            tp = TestPrint.Stub.asInterface(binder);
        }

        public void onServiceDisconnected(ComponentName name) {
        }
    }
以上是service连接的内部类,里面调用了TestPrint.Stub.asInterface(binder)方法将连接服务端之后返回的binder对象转化成一个TestPrint对象,我们连接服务端service成功之后就会调用这个方法,拿到这个对象。
        msc = new MyServiceConnection();
        intent = new Intent();
        intent.setComponent(new ComponentName("com.example.androidserver",
                "com.example.androidserver.MyService"));
        bindService(intent, msc, Context.BIND_AUTO_CREATE);
通过以上代码之后,我们定义的全局变量tp就被赋值了,就可以调用服务端的方法了。
        case R.id.print:
            if (tp != null) {
                try {
                    tp.print();
                } catch (RemoteException e) {
                    e.printStackTrace();
                }
            }
            break;
点击按钮之后就可以调用服务端实现的TestPrint接口方法进行字符串的打印了。
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值