Android AIDL(接口定义语言)简单理解和基本使用方法

一、概述   

   AIDL意思即Android  Interface Definition Language,翻过来就是Android接口定义语言,是用于定义服务端和客户端通信接口的一种描述语言,可以拿来生产IPC代码,从某种意义上说AIDL其实就是一个模板,因为在使用过程中,实际起作用的并不是AIDL文件,而是据此生产的一个Interface的实例代码,AIDL其实是为了避免我们重复写代码而出现的一个模板。
       设计AIDL这门语言的目的就是为了实现进程间通信。在Android系统中,每个进程都运行在一块独立的内存中,在其中完成自己的各项活动,与其他进程都分隔开来。可是有时候我们又有应用间进行互动的需求,比较传递数据或者任务委托等,AIDL就是为了满足这种需求而诞生的。通过AIDL,可以在一个进程中获取另一个进程的数据和调用其暴露出来的方法,从而满足进程间通信的需求。
二、语法
  AIDL语言十分简单,与java语言基本一致
  
   1、AIDL语言以.aidl为后缀名。
   2、AIDL支持的数据类型分为以下几种:

   (1)、八种基本数据类型:byte,char,short、int、long、float、double、boolean、String,CharSequence。
   (2)、实现了Parcelable接口的数据类型。
   (3)、List 类型。List承载的数据必须是AIDL支持的类型,或者是其它声明的AIDL对象。
   (4)、Map类型。Map承载的数据必须是AIDL支持的类型,或者是其它声明的AIDL对象。

三、AIDL分类(两类)

    1、第一类:声明实现了Parcelable接口的数据类型,以供其他AILD文件使用那些非默认支持的数据类型。

    2、第二类:用来定义接口方法,声明要暴露那些接口给客户端调用,定向Tag就是用来标注这些方法的参数值。

四、定向TAG

         定向Tag表示在跨进程通信中数据的流向,用于标注方法的参数。分为in,out,inout。in表示由客户端设置,out表示由服务端设置,inout是两者均可设置。此外,如果AIDL方法接口的参数值类型是:基本数据类型、String、CharSequence或者其他AIDL文件定义的方法接口,那么这些参数值的定向 Tag 默认是且只能是 in,所以除了这些类型外,其他参数值都需要明确标注使用哪种定向Tag。

五、明确导包

        在AIDL文件中需要明确标明引用到的数据类型所在包名,即使两个文件处在同个包名下。

六、注

     客户端的AIDL文件包名需要与服务端的AIDL文件包名一致,否则会报  java.lang.SecurityException:Binder invocation to an incoverect interface。

七、基本使用方法

   1.定义AIDL文件,此文件相当于一个协议,定义服务端要实现的方法。
     如:
           package com.example.aidl;  
           interface IMyService {  
                  void play();  
                 void pause();  
           }  

2.实现服务端Service:
    如:
    public class AIDLService extends Service {  
         private MyBinder mBinder;  
    @Override  
    public IBinder onBind(Intent intent) { 
          mBinder = new MyBinder();
        return mBinder;  //返回binder对象
    }  
     /*  
    * 该类继承了IMyService.Stub类而不是extends Binder类。 
     * IMyService.Stub是Binder的子类。 
     * 进程内的Service定义MyBinder内部类是继承Binder类。 
     */  
    public class MyBinder extends IMyService.Stub {  
        @Override  
        public void play() throws RemoteException {  
           Log.i(tag, "service 自定义 play()...");   
        }  
        @Override  
        public void pause() throws RemoteException {  
             Log.i(tag, "service 自定义 pause()..."); 
        }  
    }

3.把AIDL文件接口复制到Client项目
4.在Client项目中调用Service项目的服务。
如:
public class MainActivity extends Activity implements OnClickListener {  
	Button btnBind, btnPlay, btnPause;  
	IMyService mBinder; // 接口的一个引用  
	boolean mIsBind = false; // 绑定值为true,未绑定制为false;  
private ServiceConnection mConn = new ServiceConnection() {  
	@Override  
	public void onServiceDisconnected(ComponentName name) {  
  	}  
	@Override  
	public void onServiceConnected(ComponentName name, IBinder service) {  
            	/* 
             	* 获得另一个进程中的Service传递过来的IBinder对象-service, 
              	* 用IMyService.Stub.asInterface方法转换该对象,这点与进程内的通信不同 
             	 */  
            mBinder = IMyService.Stub.asInterface(service);  
  	    mIsBind = true;  
            Log.i("MainActivity", "onServiceConnected....");  
        }  
    };   
    @Override  
    protected void onCreate(Bundle savedInstanceState) {  
	 super.onCreate(savedInstanceState);  
         setContentView(R.layout.activity_main);  
	 btnBind = (Button) findViewById(R.id.btn_bind);  
         btnPlay = (Button) findViewById(R.id.btn_play);  
         btnPause = (Button) findViewById(R.id.btn_pause);  
         btnBind.setOnClickListener(this);  
	 btnPlay.setOnClickListener(this);  
         btnPause.setOnClickListener(this);  
    }   
@Override  
public void onClick(View v) {  
 	Intent intent = new Intent();  
	int btn = v.getId();  
        switch (btn) {  
        case R.id.btn_bind:  
            intent.setAction(Constant.ACTION_AIDL);  
            bindService(intent, mConn, BIND_AUTO_CREATE);
	    //绑定服务
            break;  
        case R.id.btn_play:  
            if (mIsBind){  
                try {  
                    mBinder.play(); //调用IMyService接口的方法,服务端的逻辑就可以使用
                } catch (RemoteException e) {  
                    e.printStackTrace();  
                }//调用service中的play()  
            }  
               break;  
        case R.id.btn_pause:  
            if(mIsBind){  
                try {  
                   mBinder.pause(); //调用IMyService接口的方法
                } catch (Exception e) {  
                   e.printStackTrace();  
                }  
            }  
            break;  
        }  
    }  
}  



以上可以看到,Stub是IMyService中的一个静态抽象类,继承了Binder,并且实现了IMyService接口。这也就解释了我们定义IMyInterface.Stub的时候为什么需要实现IMyService中的方法了,也说明了为什么我们可以把IMyService.Stub向上转型成IBinder了。

总结: 
        AIDL的最终效果就是让 IPC的通讯就像调用函数那样简单。自动的帮你完成了参数序列化发送以及解析返回数据的那一系列麻烦。而你所需要做的就是写上一个接口文件,然后利用aidl工具转化一下得到另一个java文件,这个文件在服务和客户端程序各放一份。服务程序继承IxxxxService.Stub 然后将函数接口里面的逻辑代码实现一下。 


  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Android AIDLAndroid Interface Definition Language)是一种用于定义客户端和服务之间通信接口的语言。AIDL 是一个 Android 特有的 RPC(远程过程调用)机制。 下面是使用 AIDL基本步骤: 1. 定义 AIDL 接口 在服务端创建一个 AIDL 文件,定义服务的接口方法。例如,创建一个名为 IMyService.aidl 的文件,其中包含以下内容: ``` interface IMyService { void sayHello(); } ``` 2. 实现 AIDL 接口 在服务端实现 AIDL 接口,例如: ``` public class MyService extends Service { private final IMyService.Stub binder = new IMyService.Stub() { @Override public void sayHello() throws RemoteException { Log.i("MyService", "Hello World"); } }; @Nullable @Override public IBinder onBind(Intent intent) { return binder; } } ``` 3. 绑定服务 在客户端绑定服务,例如: ``` private ServiceConnection connection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { IMyService myService = IMyService.Stub.asInterface(service); try { myService.sayHello(); } catch (RemoteException e) { e.printStackTrace(); } } @Override public void onServiceDisconnected(ComponentName name) { } }; private void bindService() { Intent intent = new Intent(this, MyService.class); bindService(intent, connection, Context.BIND_AUTO_CREATE); } ``` 通过上述步骤,就可以实现客户端与服务端之间的通信。需要注意的是,AIDL 接口中定义的方法必须是可序列化的。如果方法参数或返回值类型不支持序列化,可以通过 Parcelable 接口实现序列化。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值