AndroidStudio中创建AIDL Service(跨应用调用服务)

       用startService,bindService创建的服务只能在本应用程序内访问,如果要使得本程序的服务能够被其他应用程序访问,这时候就要使用远程过程调用(Remote Procedure Call,RPC)方式来实现,安卓定义了一种接口定义语言Android Interface Definition Language,简称AIDL。今天记录一下如何在Android Studio下创建AIDL Serivce。

        建立ADIL Service的步骤比建立普通Service要多一些,主要有:

        1、创建AIDL文件,在这里面定义远程接口。

        2、生成Java接口文件。

        3、建立一个Service的子类,并且记得在AndroidManifest.xml文件中配置。

       在客户端调用ADIL Servie:

        1、拷贝服务器端的AIDL文件,并生成Java接口文件。

        2、用BindService来调用Service,与调用普通Serivce相类似,只是获取IBinder的方式有点不一样。

       下面结合例子来看看,编程环境是Android Studio v1.0.1,本例子基于《疯狂Android讲义(第二版)》10.2节的例子。 本AIDL Service只有两个方法,返回一个字符串和double型数据。

一、建立AIDL文件

        在项目名称上右键>NEW>AIDL>AIDL File,这样就创建了一个ADIL文件,命名为ICat


文件内容为:

[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. // ICat.aidl  
  2. package com.sysu.aidlclient.aidlclient;  
  3.   
  4. interface ICat {  
  5.    String getColor();  
  6.    double getWeight();  
  7. }  
然后菜单中选择Build>Rebulid Project,这样就生成了java接口文件,地址在项目文件夹/app/build/generated/aidl里面。

二、编写Service子类:

        这一步跟建立普通的Serivce步骤一样,同样右键>New>Service,这样会创建一个Service的子类以及在AndroidManiFest中添加Service的的内容,主要要添加action标签并且定义android:name。它的onBind方法返回的IBinder对象要是ICat.Stub的子类的实例,ICat.Stub这个类基本不用去管它,是自动生成的。

[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. public class AidlService extends Service {  
  2.   
  3.     private CatBinder catBinder;  
  4.     //此处要继承Stub,实现ICat和IBinder接口  
  5.    <span style="color:#ff0000;"public class CatBinder extends ICat.Stub  
  6.     {  
  7.         @Override  
  8.         public String getColor() throws RemoteException {  
  9.             return "get from remote service";  
  10.         }  
  11.   
  12.         @Override  
  13.         public double getWeight() throws RemoteException {  
  14.             return 999.9;  
  15.         }  
  16.     }</span>  
  17.   
  18.     @Override  
  19.     public void onCreate() {  
  20.         super.onCreate();  
  21.         <span style="color:#ff0000;">catBinder = new CatBinder();</span>  
  22.   
  23.     @Override  
  24.     public IBinder onBind(Intent intent) {  
  25.         <span style="color:#ff0000;">return catBinder;</span>  
  26.     }  
  27.   
  28.     @Override  
  29.     public void onDestroy() {  
  30.         System.out.println("remote service destroy");  
  31.     }  
  32. }  

然后将应用部署到手机上。

三、客户端调用

        首先要拷贝AIDL文件,这里要保证文件的内容一模一样,包括包的名称,比如本例子中服务器端AIDL文件所在包的名称是com.sysu.aidlclient.aidlcilent,如何做到这一点,先新建一个项目,然后在:项目文件夹/app/src/main目录下建立一个aidl文件夹,与java文件夹同级,在Android Studio中就可以看到这个目录,在这个目录上右键New>Package,建立一个com.sysu.aidlclient.aidlclient的包,再将aidl文件拷进去。这样才能保证生成的java接口文件完全一样,否则会提示找不到接口。


      在MainActivity中调用,用bindService方法,记得要定义一个显式的intent,如红色代码获取Service的IBinder的代理

[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. private ServiceConnection conn = new ServiceConnection() {  
  2.         @Override  
  3.         public void onServiceConnected(ComponentName name, IBinder service) {  
  4.             <span style="color:#ff0000;">catService = ICat.Stub.asInterface(service);</span>  
  5.         }  
  6.   
  7.         @Override  
  8.         public void onServiceDisconnected(ComponentName name) {  
  9.             catService = null;  
  10.   
  11.         }  
  12.     };  


[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. @Override  
  2.     protected void onCreate(Bundle savedInstanceState) {  
  3.         super.onCreate(savedInstanceState);  
  4.         setContentView(R.layout.activity_main);  
  5.   
  6.         Intent intent = new Intent();  
  7.         intent.setAction("com.sysu.aidlclient.action.AIDL_SERVICE");  
  8.         //this is important  
  9.         intent.setPackage("com.sysu.aidlclient.aidlclient");  
  10.         bindService(intent,conn, Service.BIND_AUTO_CREATE);  
  11.     }  

之后就可以用catService来调用远程service中的方法了

[javascript]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. public void getRemoteService(View view)  
  2.     {  
  3.         try  
  4.         {  
  5.             Toast.makeText(this,"the color and weight is: "+catService.getColor()+":",  
  6.                     Toast.LENGTH_LONG).show();  
  7.             System.out.println(catService.getColor()+"----"+catService.getWeight());  
  8.         }catch (RemoteException e)  
  9.         {  
  10.             e.printStackTrace();  
  11.         }  
  12.         System.out.println("button click");  
  13.     }  

这里用到的AIDL只涉及到一些基本的数据类型,还可以用到一些自定义数据类型,这样步骤会稍微多一些,另开一篇文章记录。