android aidl 使用实例

最近在看Binder的实现机制,但是感觉总不是很清晰,所以想理解他的实现原理,先暂时学会怎么使用。Binder是android中的一种进程间通信机制,

android的底层是Linux系统,Linux系统中进程间通信方式主要有以下几种:

1、socket,即客户端服务器模式。所以我们客户端程序通过socket和服务器端程序进行通信,其实就是进程间通信的一个实例。

2、传统的消息队列机制

3、共享内存机制

4、信号量机制

在android系统中,由于安全性等一些其他因素影响,所以android的开发者们实现了另外一种进程间通信方式Binder,android中所有的进程间通信方式

都是通过Binder以及以上4种方式来实现的,ContentProvider实现的进程间数据共享方式就是通过共享内存以及Binder方式来实现进程间通信的,具体

的详细解释可以参考老罗的这篇博客:http://blog.csdn.net/luoshengyang/article/details/6946067。android的RPC机制(远程过程调用)也是通过Binder

机制来实现的,RPC其实就是IPC机制的一种实现方式,IPC即Interprocess communication 进程间通信,实现IPC有很多方式,但是有时候我们并不满

足于仅仅实现数据通信,有时候我们还需要去调用其它进程间的方法或对象,这时就需要RPC机制了,而android中就是通过AIDL来实现这样一种RPC

机制。具体关于RPC的定义可以google去看wiki的介绍。下面我们就来看看android的RPC机制是怎样通过AIDL(接口定义语言)来实现进程间的方法或对

象调用的。

一 、新建远程调用app(即新建一个进程),实现远程方法调用

1、新建一个AIDL文件RemoteServiceAidl.aidl,定义几个方法,分别以基本类型数据和对象作为参数。定义好之后会在工程的gen目录下生成相同的包

名以及相同文件名的java文件RemoteServiceAidl.java,他的代码我就不贴出来了。

  1. package com.lonuery.aidl;  
  2.   
  3. import com.lonuery.remote.GroupInfo;  
  4.   
  5. interface RemoteServiceAidl {  
  6.   
  7.     int calculate(int num1,int num2);  
  8.     void checkInfo(String str,double data);  
  9.       
  10.     String save(in GroupInfo groupInfo);  
  11.       
  12. }  

2、由于AIDL中传递基本数据类型和对象的方式不同,传递对象就必须实现Parcelable接口,接下来定义GroupInfo类

[java]  view plain copy print ? 在CODE上查看代码片 派生到我的代码片
  1. public class GroupInfo implements Parcelable{  
  2.       
  3.     String name,groupId,memCount;  
  4.       
  5.     public GroupInfo(String name,String groupId,String memCount){  
  6.         this.name = name;  
  7.         this.groupId = groupId;  
  8.         this.memCount = memCount;  
  9.     }  
  10.       
  11.     public String getName() {  
  12.         return name;  
  13.     }  
  14.       
  15.     public void setName(String name) {  
  16.         this.name = name;  
  17.     }  
  18.       
  19.     public String getGroupId() {  
  20.         return groupId;  
  21.     }  
  22.       
  23.     public void setGroupId(String groupId) {  
  24.         this.groupId = groupId;  
  25.     }  
  26.       
  27.     public String getMemCount() {  
  28.         return memCount;  
  29.     }  
  30.       
  31.     public void setMemCount(String memCount) {  
  32.         this.memCount = memCount;  
  33.     }  
  34.       
  35.     @Override  
  36.     public int describeContents() {  
  37.         return 0;  
  38.     }  
  39.       
  40.     @Override  
  41.     public void writeToParcel(Parcel parcel, int arg1) {  
  42.         //参数的写入是什么顺序,那么下面参数的读取就应该是什么顺序。参数的写入顺序不对,会导致读取的参数顺序不对  
  43.         parcel.writeString(this.name);  
  44.         parcel.writeString(this.groupId);  
  45.         parcel.writeString(this.memCount);  
  46.     }  
  47.     //如果要传递对象那么这个类中就必须创建一个名字为CREATOR的Creator对象。  
  48.     public static final Parcelable.Creator<GroupInfo> CREATOR =   
  49.                 new Parcelable.Creator<GroupInfo>() {  
  50.   
  51.         @Override  
  52.         public GroupInfo createFromParcel(Parcel parcel) {  
  53.             return new GroupInfo(parcel.readString(), parcel.readString(), parcel.readString());  
  54.         }  
  55.   
  56.         @Override  
  57.         public GroupInfo[] newArray(int size) {  
  58.             return new GroupInfo[size];  
  59.         }  
  60.     };  
  61. }  

3、在GroupInfo.java相同包下定义GroupInfo.aidl文件。

  1. package com.lonuery.remote;  
  2.   
  3. parcelable GroupInfo;  

3、实现RemoteServiceAidl.Stub类,并且定义一个Service以供其他程序来远程绑定,返回Stub的对象。

[java]  view plain copy print ? 在CODE上查看代码片 派生到我的代码片
  1. public class RemoteService extends Service{  
  2.   
  3.     String TAG = "RemoteService";  
  4.     AidlImpl aidlService = new AidlImpl();  
  5.     @Override  
  6.     public IBinder onBind(Intent arg0) {  
  7.         Log.v(TAG, "onBind");  
  8.         return aidlService;  
  9.     }  
  10.       
  11.     class AidlImpl extends RemoteServiceAidl.Stub{  
  12.   
  13.         @Override  
  14.         public int calculate(int num1, int num2) throws RemoteException {  
  15.             int result = num1*num2;  
  16.               
  17.             return result;  
  18.         }  
  19.   
  20.         @Override  
  21.         public void checkInfo(String str, double data) throws RemoteException {  
  22.             if(str!=null){        
  23.                 Log.v("checkInfo""输出");  
  24.             }  
  25.         }  
  26.   
  27.         @Override  
  28.         public String save(GroupInfo groupInfo) throws RemoteException {  
  29.             String str = null;  
  30.             if(groupInfo!=null){  
  31.                 if(groupInfo.getGroupId().equals("电话")){  
  32.                     str = "地方金额1";  
  33.                 }else if(groupInfo.getMemCount().equals("电话")){  
  34.                     str = "地方金额2";  
  35.                 }else if(groupInfo.getName().equals("电话")){  
  36.                     str = "地方金额3";  
  37.                 }  
  38.             }  
  39.             return str;   
  40.         }  
  41.     }  
  42. }  

二、新建调用app即新建调用进程

1、在新建的调用app中新建和RemoteServiceAidl.aidl相同的包名,并将RemoteServiceAidl.aidl复制到这个包中。同样,在gen目录下也会自动生成

RemoteServiceAidl.java的文件。

2、新建和GroupInfo.java相同的包名并将GroupInfo.java和GroupInfo.aidl文件复制到此包中。

3、绑定远程服务,利用远程服务对象,调用远程方法。

[java]  view plain copy print ? 在CODE上查看代码片 派生到我的代码片
  1. public class MainActivity extends Activity implements OnClickListener{  
  2.   
  3.     Button btn1;  
  4.     RemoteServiceAidl remoteService;  
  5.     TextView tv;  
  6.     @Override  
  7.     protected void onCreate(Bundle savedInstanceState) {  
  8.         super.onCreate(savedInstanceState);  
  9.         setContentView(R.layout.activity_main);  
  10.           
  11.         btn1 = (Button)findViewById(R.id.button1);        
  12.         btn1.setOnClickListener(this);  
  13.           
  14.         tv = (TextView)findViewById(R.id.textView1);  
  15.           
  16.         bindService(new Intent(RemoteServiceAidl.class.getName()), connection,   
  17.                 Context.BIND_AUTO_CREATE);  
  18.           
  19.     }  
  20.       
  21.     @Override  
  22.     public void onClick(View view) {  
  23.         if(view.getId()==R.id.button1){  
  24.             try {  
  25.                 int result=0;  
  26.                 GroupInfo info = new GroupInfo("""电话""");  
  27.                 String str=null;  
  28.                 try {  
  29.                     result = remoteService.calculate(68);  
  30.                     str = remoteService.save(info);  
  31.                 } catch (DeadObjectException e) {  
  32.                     e.printStackTrace();  
  33.                 }  
  34.                 tv.setText("result:"+result);                 
  35.                 String text = tv.getText().toString() + "Id:"+str;  
  36.                 tv.setText(text);  
  37.             } catch (RemoteException e) {  
  38.                 e.printStackTrace();  
  39.             }  
  40.         }     
  41.     }  
  42.   
  43.     @Override  
  44.     protected void onDestroy() {  
  45.         unbindService(connection);  
  46.         super.onDestroy();  
  47.     }  
  48.       
  49.     private ServiceConnection connection = new ServiceConnection() {  
  50.           
  51.         @Override  
  52.         public void onServiceDisconnected(ComponentName arg0) {  
  53.             remoteService = null;  
  54.         }  
  55.           
  56.         @Override  
  57.         public void onServiceConnected(ComponentName arg0, IBinder binder) {  
  58.             remoteService = RemoteServiceAidl.Stub.asInterface(binder);  
  59.         }  
  60.     };  
  61. }  

4、在AndroidManifest.xml中对所创建的服务进行注册。

接下来我们分别安装远程app,和调用app,来看一下效果。

好了android中aidl的使用实例就完成了,接下来我们总结一下:

1、RemoteService只是一个代理的角色,他的作用就是让其他的进程来绑定他,然后通过他进行远程方法调用,真正的调用其实是在

RemoteServiceAidl.Stub的实现类AidlImpl中实现的。

2、将AidlImpl类的对象返回给RemoteService的绑定接口onBind,远程调用就是通过这个接口来获取AidlImpl对象,继而实现方法的调用。

3、远程进程通过bindService方法绑定远程服务RemoteService。

实例已经上传到csdn上http://download.csdn.net/detail/zkw12358/7362967

免费:http://download.csdn.net/detail/huningjun/8699557 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值