AIDL的使用

来源:互联网 发布:javascript随机整数 编辑:程序博客网 时间:2024/06/06 00:39

aidl可用于进程间的通讯,我们都知道一个安卓应用程序对应一个虚拟机,原则上是不允许不同的虚拟机之间通信的,这时候就出来远程服务aidl它可以进行不同进程间的通讯。

aidl它其实是一种语言IPC,是通过binder实现的(具体原理下一篇中讲解)

下面我们来看一个晓得例子:
新建一个项目起名为远程服务:
RemoteService:
这里写图片描述

这个远程服务要被另外一个项目调用:

第一步创建一个远程服务RemoteService集成Service代码如下:

package com.example.aidl;import com.example.aidl.invoke.IService;import com.example.aidl.invoke.IService.Stub;import android.app.Service;import android.content.Intent;import android.os.Binder;import android.os.IBinder;/** * 远程服务 * @author Administrator * */public class RemoteService extends Service {    @Override    public IBinder onBind(Intent arg0) {        return new MyBinder();    }    // 业务逻辑方法    public void serviceMethod(){        System.out.println("*************************");    }    //  创建一个供外部调用逻辑的中间类    private class MyBinder extends Stub{        @Override        public void callMethod() {            //调用服务的业务逻辑方法            serviceMethod();        }    }}

上面代码中中间类刚开始是继承IService的,刚开始是创建的IService是一个接口扩展名是Java的,如下:

package com.example.aidl.invoke;/** * 供外面调用的接口 * @author Administrator * */ interface IService {    /**     * 供外面操作调用的方法     */    void callMethod();}

然后再远程项目中测试一下服务,看是否好使,代码如下:

package com.example.aidl;import com.example.aidl.invoke.IService;import android.app.Activity;import android.content.ComponentName;import android.content.Intent;import android.content.ServiceConnection;import android.os.Bundle;import android.os.IBinder;import android.os.RemoteException;import android.view.View;public class MainActivity extends Activity {    private IService  myBinder;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);    }    //绑定服务    public void bindService(View v){        // 测试一下绑定的服务        Intent intent = new Intent(this,RemoteService.class);        bindService(intent, new MyConntion(), BIND_AUTO_CREATE);    }    //本地调用服务中的方法    public void callServiceMethod(View v){        //调用服务中的业务逻辑方法        try {            myBinder.callMethod();        } catch (RemoteException e) {            // TODO Auto-generated catch block            e.printStackTrace();        }    }    /**     * 实现服务的连接     * @author Administrator     *     */    private class MyConntion implements ServiceConnection{        @Override        public void onServiceConnected(ComponentName arg0, IBinder arg1) {            myBinder =  (IService) arg1;        }        @Override        public void onServiceDisconnected(ComponentName arg0) {        }    }}

接下来开始在创建一个项目
这里写图片描述

这里需要把上面远程服务所在的项目的IService的扩展名改为aidl

package com.example.aidl.invoke;/** * 供外面调用的接口 * @author Administrator * */ interface IService {    /**     * 供外面操作调用的方法     */    void callMethod();}

把这个扩展名为aidl的文件复制到NativeAPP中,注意连同包名一起复制,这里有个小问题,就是在清单文件中需要价格action:

<service android:name="com.example.aidl.RemoteService">            <intent-filter >                <action android:name="com.example.aidl.fly"/>            </intent-filter>        </service>

再说明一点,扩展名改为aidl的时候,会在gen文件下面生成一个文件:

/* * This file is auto-generated.  DO NOT MODIFY. * Original file: D:\\android_EclipseDemo\\RemoteService\\src\\com\\example\\aidl\\invoke\\IService.aidl */package com.example.aidl.invoke;/** * 供外面调用的接口 * @author Administrator * */public interface IService extends android.os.IInterface{/** Local-side IPC implementation stub class. */public static abstract class Stub extends android.os.Binder implements com.example.aidl.invoke.IService{private static final java.lang.String DESCRIPTOR = "com.example.aidl.invoke.IService";/** Construct the stub at attach it to the interface. */public Stub(){this.attachInterface(this, DESCRIPTOR);}/** * Cast an IBinder object into an com.example.aidl.invoke.IService interface, * generating a proxy if needed. */public static com.example.aidl.invoke.IService asInterface(android.os.IBinder obj){if ((obj==null)) {return null;}android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);if (((iin!=null)&&(iin instanceof com.example.aidl.invoke.IService))) {return ((com.example.aidl.invoke.IService)iin);}return new com.example.aidl.invoke.IService.Stub.Proxy(obj);}@Override public android.os.IBinder asBinder(){return this;}@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_callMethod:{data.enforceInterface(DESCRIPTOR);this.callMethod();reply.writeNoException();return true;}}return super.onTransact(code, data, reply, flags);}private static class Proxy implements com.example.aidl.invoke.IService{private android.os.IBinder mRemote;Proxy(android.os.IBinder remote){mRemote = remote;}@Override public android.os.IBinder asBinder(){return mRemote;}public java.lang.String getInterfaceDescriptor(){return DESCRIPTOR;}/**     * 供外面操作调用的方法     */@Override public void callMethod() throws android.os.RemoteException{android.os.Parcel _data = android.os.Parcel.obtain();android.os.Parcel _reply = android.os.Parcel.obtain();try {_data.writeInterfaceToken(DESCRIPTOR);mRemote.transact(Stub.TRANSACTION_callMethod, _data, _reply, 0);_reply.readException();}finally {_reply.recycle();_data.recycle();}}}static final int TRANSACTION_callMethod = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);}/**     * 供外面操作调用的方法     */public void callMethod() throws android.os.RemoteException;}

重点看这里:

public static abstract class Stub extends android.os.Binder implements com.example.aidl.invoke.IService{

也就是在代码中不需要去实现IService这个接口,直接继承Stub这个类就好了,

在NativeAPP项目中调用远程服务的方法:

package com.example.nativeapp;import com.example.aidl.invoke.IService;import com.example.aidl.invoke.IService.Stub;import android.app.Activity;import android.content.ComponentName;import android.content.Intent;import android.content.ServiceConnection;import android.os.Bundle;import android.os.IBinder;import android.os.RemoteException;import android.view.View;public class MainActivity extends Activity {    private IService asInterface;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);    }    public void bindService(View v){        // 隐士意图启动服务        Intent intent = new Intent();        intent.setAction("com.example.aidl.fly");        bindService(intent, new MyConntion(), BIND_AUTO_CREATE);    }    //远程服务调用的方法    public void callServiceMethod(View v){        try {            asInterface.callMethod();        } catch (RemoteException e) {            e.printStackTrace();        }    }    /**     * 服务连接     * @author Administrator     *     */    private class MyConntion implements ServiceConnection{        @Override        public void onServiceConnected(ComponentName arg0, IBinder arg1) {            asInterface = Stub.asInterface(arg1);        }        @Override        public void onServiceDisconnected(ComponentName arg0) {        }    }}

这样就基本实现了aidl跨进程通信。

0 0
原创粉丝点击