AIDL跨进程通信在Android的应用

来源:互联网 发布:域名投资人联系 编辑:程序博客网 时间:2024/06/04 19:39

             一个Android应用程序就是一个进程,而Java并不支持跨进程的内存共享,所以在两个Android应用程序之间不能直接共享内存,那么两个Android应用程序之间要传递对象那该怎么解决呢?那么就需要一套不同进程间的通信机制。那么这是就可以用AIDL(Android Interface Definition language )了,它是一种IDL语言,用于生成可以在Android设备上两个进程之间进行进程间通信(IPC)的代码,她能把对象解析成操作系统能够理解的数据格式,以达到跨界对象访问的目的。如果在一个进程中(例如Activity)要调用另一个进程中(例如Service)对象的操作,就可以使用AIDL生成可序列化的参数。

下面通过一个例子讲解一下AIDL的具体用法。

      打开Android Studio新建一个工程,然后新建一个继承Service的服务类,在该类中的onBind方法中可以写条控制台输出语句,方便绑定服务时观察程序执行情况。在onCreate方法里写一个线程,让它每2s输出一条信息,及时观察数据的改变:

@Overridepublic void onCreate() {    super.onCreate();    System.out.println("start service");        new Thread() {            @Override            public void run() {                super.run();                runing = true;                while (runing){                    try {                        Thread.sleep(2000);                    } catch (InterruptedException e) {                        e.printStackTrace();                    }                    System.out.println(data);                }            }        }.start();}

可以现在这个应用里面开启服务和关闭服务观察一下效果。

下面建立第二个应用,在该工作空间里新建一个module,我们需要在这个应用的Activity里面启动前面我们创建好的应用程序里的服务。在布局里面新建4个按钮,分别是:启动另一个进程的服务,暂停另一个进程的服务,绑定另一进程的服务,解除另一个进程的绑定,然后再增加一个EditText和Button,EditText用于获取用户输入的数据,Button用于同步两个进程的数据,也就是将数据从当前应用传统到另一个应用。两个工程建好了,下面就是解决两个进程间的数据通信,这时我们就要用AIDL机制了。

下面讲解AIDL机制的实现:

在上面建的第一个应用(也就是带service的那个)里面新建一个AIDL文件:

新建后再main目录下会出现一个aidl的文件夹,里面有一个文件类型为aidl的文件,然后在文件里面写个方法,用于接收数据。那另一个进程怎么把数据传输过来的呢?

首先我们在第二个应用程序里面通过bindService方法和第一个应用的服务绑定,这个大家都懂啥,这一点不牵涉到AIDL,不通过AIDL是可以实习一个应用启动或者绑定另一个应用的服务,只是布不能实现内存的共享,在执行bindService方法后,会执行第一个service类里面的onBind方法并需要返回一个IBinder对象,在Android开发中,绑定服务可以返回一个对象,那两个进程怎么实现对象传输呢?

我们需要在第二个应用里面也建一个aidl文件,而且文件包名必须和第一个的相同,建立好后将第一个aidl文件里面的文件拷贝到第二个,这样两个应用就有了相同的aidl。



然后我们将第一个服务类里面的onBind方法里返回这个对象:

@Overridepublic IBinder onBind(Intent intent) {    // TODO: Return the communication channel to the service.    System.out.println("onband service");    return new AppServiceRemoteBlander.Stub() {        @Override        public void basicTypes(int anInt, long aLong, boolean aBoolean,                               float aFloat, double aDouble, String aString) throws RemoteException {        }        @Override        public void setData(String data) throws RemoteException {            AppService.this.data = data;        }    };}
setData是在aidl里面自定义的方法,由于是接口,所以需要实现。然后再第二个应用的onServiceConnected里面获取这个对象,onServiceConnected会在绑定成功后自动调用。

@Overridepublic void onServiceConnected(ComponentName name, IBinder service) {    System.out.println("band service success");    System.out.println(service);    binder = AppServiceRemoteBlander.Stub.asInterface(service);}

binder = AppServiceRemoteBlander.Stub.asInterface(service);
这一句不能用强制类型转换成aidl的类型,毕竟两个应用的对象在不同的内存,所以用上面提供的方法转换。

现在获得了对象,就可以调用steData方法将EditText的文本传递过去了。到这里差不多就可以了,一个简单的AIDL应用就诞生了

需要注意的是:

第一点:观察控制台的输出时,是那个应用输出的就要却换到相应的应用,不然看不到对应的输出效果:



第二点:由于对象实在onBind放法里面返回的,所以必须执行绑定操作才有对象返回,不然不能进行数据的传输,点击同步数据时程序会挂掉的

第三点:android5.0及以后启动服务必须显示启动

工程下载地址:http://download.csdn.net/detail/tuoguang/9152267





0 0
原创粉丝点击