MyException - 我的异常网
当前位置:我的异常网» 人工智能 » Android AIDL(Android Interface Definition Langua

Android AIDL(Android Interface Definition Language)引见

www.MyException.Cn  网友分享于:2015-08-26  浏览:9次
Android AIDL(Android Interface Definition Language)介绍

在网上看到一篇介绍AIDL的文章,自己把代码在2.2的sdk上跑了一下,稍微更改了一下原文中的代码(下文中的代码都是自己编译通过后使用的代码)并且添加了xml文件,大家可以按照这个代码自己实现一遍。

以下部门来自网上其他朋友的文章(由于出处太多,无法找到原始的地址)

================================================================

Android每个应用程序都可以有自己的进程在写UI应用的时候经常要用到Service. 在不同的进程中怎样传递对象呢?  显然, Java中不允许跨进程内存共享因此传递对象只能把对象拆分成操作系统能理解的简单形式以达到跨界对象访问的目的J2EE,采用RMI的方式可以通过序列化传递对象Android则采用AIDL的方式理论上AIDL可以传递Bundle,实际上做起来却比较麻烦.

 

AIDL(AndRoid接口描述语言)是一种接口描述语言编译器可以通过aidl文件生成一段代码,通过预先定义的接口达到两个进程内部通信进程的目的如果需要在一个Activity访问另一个Service中的某个对象需要先将对象转化成AIDL可识别的参数(可能是多个参数), 然后使用AIDL来传递这些参数在消息的接收端使用这些参数组装成自己需要的对象.

AIDLIPC的机制和COMCORBA类似是基于接口的,但它是轻量级的。它使用代理类在客户端和实现层间传递值如果要使用AIDL, 需要完成2件事情: 1. 引入AIDL的相关类.; 2. 调用aidl产生的class.

具体实现步骤如下:

1、创建AIDL文件在这个文件里面定义接口该接口定义了可供客户端访问的方法和属性。

: ITaskBinder.adil

  1. package com.android.aidltest; 
  2. import com.android.aidltest.ITaskCallback; 
  3.  
  4. interface ITaskBinder { 
  5.     boolean isTaskRunning(); 
  6.     void stopRunningTask(); 
  7.     void registerCallback(ITaskCallback cb); 
  8.     void unregisterCallback(ITaskCallback cb); 


其中: ITaskCallback在文件ITaskCallback.aidl中定义: 

  1. package com.android.aidltest; 
  2.  
  3. interface ITaskCallback {   
  4.  
  5.     void actionPerformed(int actionId);  
  6. }  

注意理论上参数可以传递基本数据类型和String, 还有就是Bundle的派生类不过在Eclipse,目前的ADT不支持Bundle做为参数据说用Ant编译可以我没做尝试.

2、编译AIDL文件Ant的话可能需要手动使用Eclipse plugin的话,可以根据adil文件自动生产java文件并编译不需要人为介入.

3、在Java文件中实现AIDL中定义的接口编译器会根据AIDL接口产生一个JAVA接口。这个接口有一个名为Stub的内部抽象类,它继承扩展了接口并实现了远程调用需要的几个方法。接下来就需要自己去实现自定义的几个接口了.

ITaskBinder.aidl中接口的实现MyService.java中接口以内嵌类的方式实现:

  1. private final ITaskBinder.Stub mBinder = new ITaskBinder.Stub() { 
  2.              
  3.     @Override 
  4.     public void unregisterCallback(ITaskCallback cb) throws RemoteException { 
  5.         printf("service on unregisterCallback"); 
  6.         // TODO Auto-generated method stub 
  7.         if(cb!=null
  8.             mCallbacks.unregister(cb); 
  9.     } 
  10.      
  11.     @Override 
  12.     public void stopRunningTask() throws RemoteException { 
  13.         printf("service on stopRunningTask"); 
  14.         // TODO Auto-generated method stub 
  15.          
  16.     } 
  17.      
  18.     @Override 
  19.     public void registerCallback(ITaskCallback cb) throws RemoteException { 
  20.         printf("service on registerCallback"); 
  21.         // TODO Auto-generated method stub 
  22.         if(cb!=null
  23.             mCallbacks.register(cb); 
  24.     } 
  25.      
  26.     @Override 
  27.     public boolean isTaskRunning() throws RemoteException { 
  28.         printf("service on isTaskRunning"); 
  29.         // TODO Auto-generated method stub 
  30.         return false
  31.     } 
  32. }; 

aidltest.javaITaskCallback.aidl接口实现:

  1.    private ITaskCallback mCallback = new ITaskCallback.Stub() { 
  2.     @Override 
  3.     public void actionPerformed(int actionId) throws RemoteException { 
  4.         // TODO Auto-generated method stub 
  5.         printf("callback id = " + actionId); 
  6.     } 
  7. }; 

4、向客户端提供接口ITaskBinder, 如果写的是service,扩展该Service并重载onBind ()方法来返回一个实现上述接口的类的实例。这个地方返回的mBinder,就是上面通过内嵌了定义的那个. (MyService.java)

  1. public IBinder onBind(Intent t) { 

  2.     printf("service on bind"); 

  3.     return mBinder; 

Activity可以通过Binder定义的接口来进行远程调用.

5、在服务器端回调客户端的函数前提是当客户端获取的IBinder接口的时候,要去注册回调函数只有这样服务器端才知道该调用那些函数在:MyService.java:

  1. void callback(int val) { 
  2.     final int N = mCallbacks.beginBroadcast(); 
  3.     for (int i = 0; i < N; i++) { 
  4.         try { 
  5.             mCallbacks.getBroadcastItem(i).actionPerformed(val); 
  6.         }catch(RemoteException e) { 
  7.              
  8.         } 
  9.     } 
  10.     mCallbacks.finishBroadcast(); 

AIDL的创建方法:

AIDL语法很简单,可以用来声明一个带一个或多个方法的接口,也可以传递参数和返回值。 由于远程调用的需要这些参数和返回值并不是任何类型.下面是些AIDL支持的数据类型:

1. 不需要import声明的简单Java编程语言类型(int,boolean)

2. String, CharSequence不需要特殊声明

3. List, MapParcelables类型, 这些类型内所包含的数据成员也只能是简单数据类型, String等其他比支持的类型.

(另外: 我没尝试Parcelables, Eclipse+ADT下编译不过, 或许以后会有所支持).


实现接口时有几个原则:

.抛出的异常不要返回给调用者. 跨进程抛异常处理是不可取的.

.IPC调用是同步的。如果你知道一个IPC服务需要超过几毫秒的时间才能完成地话,你应该避免在Activity的主线程中调用。 也就是IPC调用会挂起应用程序导致界面失去响应. 这种情况应该考虑单起一个线程来处理.

.不能在AIDL接口中声明静态属性。

IPC
的调用步骤:

 1. 声明一个接口类型的变量,该接口类型在.aidl文件中定义。

2. 实现ServiceConnection

3. 调用ApplicationContext.bindService(),并在ServiceConnection实现中进行传递.

 4. ServiceConnection.onServiceConnected()实现中,你会接收一个IBinder实例(被调用的Service). 调用

    YourInterfaceName.Stub.asInterface((IBinder)service)将参数转换为YourInterface类型。

5. 调用接口中定义的方法。 你总要检测到DeadObjectException异常,该异常在连接断开时被抛出。它只会被远程方法抛出。

6. 断开连接,调用接口实例中的ApplicationContext.unbindService()

 下面是整个程序:

1. ITaskCallback.aidl 

  1. package com.android.aidltest; 
  2.  
  3. interface ITaskCallback { 
  4.     void actionPerformed(int actionId); 

 2. ITaskBinder.aidl

  1. package com.android.aidltest; 
  2. import com.android.aidltest.ITaskCallback; 
  3.  
  4. interface ITaskBinder { 
  5.     boolean isTaskRunning(); 
  6.     void stopRunningTask(); 
  7.     void registerCallback(ITaskCallback cb); 
  8.     void unregisterCallback(ITaskCallback cb); 

 3.  MyService.java

  1. package com.android.aidltest; 
  2.  
  3. import android.app.Service; 
  4. import android.content.Intent; 
  5. import android.os.IBinder; 
  6. import android.os.RemoteCallbackList; 
  7. import android.os.RemoteException; 
  8. import android.util.Log; 
  9.  
  10. public class MyService extends Service { 
  11.     public void onCreate() { 
  12.         printf("service create"); 
  13.     } 
  14.      
  15.     public void onStart(Intent intent, int startId) { 
  16.         printf("service start id = " + startId); 
  17.         callback(startId); 
  18.     } 
  19.      
  20.  
  21.     @Override 
  22.     public IBinder onBind(Intent intent) { 
  23.         // TODO Auto-generated method stub 
  24.         printf("service on bind"); 
  25.         return mBinder; 
  26.     } 
  27.      
  28.     public void onDestroy() { 
  29.         printf("service on destroy"); 
  30.         super.onDestroy(); 
  31.     } 
  32.      
  33.     public boolean onUnbind(Intent intent) { 
  34.         printf("service on unbind"); 
  35.         return super.onUnbind(intent); 
  36.     } 
  37.      
  38.     public void onRebind(Intent intent) { 
  39.         printf("service on rebind"); 
  40.         super.onRebind(intent); 
  41.     } 
  42.      
  43.     private void printf(String str) { 
  44.         Log.e("TAG","#######################---"+str+"-------"); 
  45.          
  46.     } 
  47.      
  48.     void callback(int val) { 
  49.         final int N = mCallbacks.beginBroadcast(); 
  50.         for (int i = 0; i < N; i++) { 
  51.             try { 
  52.                 mCallbacks.getBroadcastItem(i).actionPerformed(val); 
  53.             }catch(RemoteException e) { 
  54.                  
  55.             } 
  56.         } 
  57.         mCallbacks.finishBroadcast(); 
  58.     } 
  59.      
  60.     private final ITaskBinder.Stub mBinder = new ITaskBinder.Stub() { 
  61.                  
  62.         @Override 
  63.         public void unregisterCallback(ITaskCallback cb) throws RemoteException { 
  64.             printf("service on unregisterCallback"); 
  65.             // TODO Auto-generated method stub 
  66.             if(cb!=null
  67.                 mCallbacks.unregister(cb); 
  68.         } 
  69.          
  70.         @Override 
  71.         public void stopRunningTask() throws RemoteException { 
  72.             printf("service on stopRunningTask"); 
  73.             // TODO Auto-generated method stub           
  74.         } 
  75.          
  76.         @Override 
  77.         public void registerCallback(ITaskCallback cb) throws RemoteException { 
  78.             printf("service on registerCallback"); 
  79.             // TODO Auto-generated method stub 
  80.             if(cb!=null
  81.                 mCallbacks.register(cb); 
  82.         } 
  83.          
  84.         @Override 
  85.         public boolean isTaskRunning() throws RemoteException { 
  86.             printf("service on isTaskRunning"); 
  87.             // TODO Auto-generated method stub 
  88.             return false
  89.         } 
  90.     }; 
  91.      
  92.     final RemoteCallbackList<ITaskCallback> mCallbacks 
  93.     = new RemoteCallbackList<ITaskCallback>(); 

 4. aidltest.java

  1. package com.android.aidltest; 
  2.  
  3. import android.app.Activity; 
  4. import android.content.ComponentName; 
  5. import android.content.Context; 
  6. import android.content.Intent; 
  7. import android.content.ServiceConnection; 
  8. import android.os.Bundle; 
  9. import android.os.IBinder; 
  10. import android.os.RemoteException; 
  11. import android.util.Log; 
  12. import android.view.View; 
  13. import android.view.View.OnClickListener; 
  14. import android.widget.Button; 
  15.  
  16. public class AidlTest extends Activity { 
  17.     private Button btnOk; 
  18.     private Button btnCancel; 
  19.      
  20.     /** Called when the activity is first created. */ 
  21.     @Override 
  22.     public void onCreate(Bundle savedInstanceState) { 
  23.         super.onCreate(savedInstanceState); 
  24.         setContentView(R.layout.main); 
  25.          
  26.         btnOk = (Button)findViewById(R.id.btn_ok); 
  27.         btnCancel = (Button)findViewById(R.id.btn_cancel); 
  28.          
  29.         btnOk.setText("Start Service"); 
  30.         btnCancel.setText("Stop Service"); 
  31.          
  32.         btnOk.setOnClickListener(new OnClickListener() { 
  33.             public void onClick(View v) { 
  34.                 onOkClick(); 
  35.             } 
  36.         }); 
  37.          
  38.         btnCancel.setOnClickListener(new OnClickListener() { 
  39.             public void onClick(View v) { 
  40.                 onCancelClick(); 
  41.             } 
  42.         }); 
  43.     } 
  44.     void onOkClick() {   
  45.         printf("clicked ok"); 
  46.         Bundle args = new Bundle(); 
  47.  
  48.         Intent intent = new Intent(this, MyService.class); 
  49.         intent.putExtras(args); 
  50.  
  51.         bindService(intent, mConnection, Context.BIND_AUTO_CREATE); 
  52.         startService(intent);                    
  53.     } 
  54.  
  55.     void onCancelClick() { 
  56.         printf("clicked cancel"); 
  57.         Intent intent = new Intent(this, MyService.class); 
  58.         unbindService(mConnection); 
  59.     } 
  60.      
  61.     private void printf(String str) { 
  62.         Log.e("TAG""##################-------"+str+"-----"); 
  63.     } 
  64.     ITaskBinder mService; 
  65.      
  66.     private ServiceConnection mConnection = new ServiceConnection() { 
  67.         public void onServiceConnected(ComponentName className, 
  68.                 IBinder service) { 
  69.             mService = ITaskBinder.Stub.asInterface(service); 
  70.              
  71.             try { 
  72.                 mService.registerCallback(mCallback); 
  73.             }catch (RemoteException e) { 
  74.              
  75.             } 
  76.         } 
  77.         public void onServiceDisconnected(ComponentName className) { 
  78.             mService = null
  79.         } 
  80.     }; 
  81.      
  82.     private ITaskCallback mCallback = new ITaskCallback.Stub() { 
  83.         @Override 
  84.         public void actionPerformed(int actionId) throws RemoteException { 
  85.             // TODO Auto-generated method stub 
  86.             printf("callback id = " + actionId); 
  87.         } 
  88.     }; 

 5. xml文件

AndroidMenifest.xml

  1. <?xml version="1.0" encoding="utf-8"?> 
  2. <manifest xmlns:android="http://schemas.android.com/apk/res/android" 
  3.       package="com.android.aidltest" 
  4.       android:versionCode="1" 
  5.       android:versionName="1.0"> 
  6.     <application android:icon="@drawable/icon" android:label="@string/app_name"> 
  7.         <activity android:name=".AidlTest" 
  8.                   android:label="@string/app_name"> 
  9.             <intent-filter> 
  10.                 <action android:name="android.intent.action.MAIN" /> 
  11.                 <category android:name="android.intent.category.LAUNCHER" /> 
  12.             </intent-filter> 
  13.         </activity> 
  14.          
  15.         <service android:name=".MyService" > 
  16.             <intent-filter> 
  17.                 <action android:name="com.android.aidltest.START_MYSERVICE" /> 
  18.                 <category android:name="android.intent.category.DEFAULT" /> 
  19.             </intent-filter> 
  20.         </service> 
  21.          
  22.     </application> 
  23.     <uses-sdk android:minSdkVersion="8" /> 
  24.  
  25. </manifest>  

 main.xml

  1. <?xml version="1.0" encoding="utf-8"?> 
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
  3.     android:orientation="vertical" 
  4.     android:layout_width="fill_parent" 
  5.     android:layout_height="fill_parent" 
  6.     > 
  7. <TextView   
  8.     android:layout_width="fill_parent"  
  9.     android:layout_height="wrap_content"  
  10.     android:text="@string/hello" 
  11.     /> 
  12. <Button  
  13.     android:id="@+id/btn_ok" 
  14.     android:layout_width="wrap_content" 
  15.     android:layout_height="wrap_content" 
  16.     android:text="@string/btn_ok"  
  17.     /> 
  18. <Button  
  19.     android:id="@+id/btn_cancel" 
  20.     android:layout_width="wrap_content" 
  21.     android:layout_height="wrap_content" 
  22.     android:text="@string/btn_cancel"  
  23.     /> 
  24. </LinearLayout> 

string.xml

  1. <?xml version="1.0" encoding="utf-8"?> 
  2. <resources> 
  3.     <string name="hello">Hello World, AidlTest!</string> 
  4.     <string name="app_name">AIDL Test</string> 
  5.     <string name="btn_ok">OK</string> 
  6.     <string name="btn_cancel">Cancel</string> 
  7. </resources> 

文章评论

写给自己也写给你 自己到底该何去何从
写给自己也写给你 自己到底该何去何从
程序员周末都喜欢做什么?
程序员周末都喜欢做什么?
不懂技术不要对懂技术的人说这很容易实现
不懂技术不要对懂技术的人说这很容易实现
60个开发者不容错过的免费资源库
60个开发者不容错过的免费资源库
程序员应该关注的一些事儿
程序员应该关注的一些事儿
团队中“技术大拿”并非越多越好
团队中“技术大拿”并非越多越好
程序员必看的十大电影
程序员必看的十大电影
当下全球最炙手可热的八位少年创业者
当下全球最炙手可热的八位少年创业者
初级 vs 高级开发者 哪个性价比更高?
初级 vs 高级开发者 哪个性价比更高?
程序员的鄙视链
程序员的鄙视链
旅行,写作,编程
旅行,写作,编程
我是如何打败拖延症的
我是如何打败拖延症的
漫画:程序员的工作
漫画:程序员的工作
Google伦敦新总部 犹如星级庄园
Google伦敦新总部 犹如星级庄园
如何成为一名黑客
如何成为一名黑客
总结2014中国互联网十大段子
总结2014中国互联网十大段子
我的丈夫是个程序员
我的丈夫是个程序员
Web开发人员为什么越来越懒了?
Web开发人员为什么越来越懒了?
程序员的一天:一寸光阴一寸金
程序员的一天:一寸光阴一寸金
十大编程算法助程序员走上高手之路
十大编程算法助程序员走上高手之路
Java程序员必看电影
Java程序员必看电影
老程序员的下场
老程序员的下场
程序员和编码员之间的区别
程序员和编码员之间的区别
做程序猿的老婆应该注意的一些事情
做程序猿的老婆应该注意的一些事情
科技史上最臭名昭著的13大罪犯
科技史上最臭名昭著的13大罪犯
老美怎么看待阿里赴美上市
老美怎么看待阿里赴美上市
程序员最害怕的5件事 你中招了吗?
程序员最害怕的5件事 你中招了吗?
编程语言是女人
编程语言是女人
5款最佳正则表达式编辑调试器
5款最佳正则表达式编辑调试器
程序猿的崛起——Growth Hacker
程序猿的崛起——Growth Hacker
要嫁就嫁程序猿—钱多话少死的早
要嫁就嫁程序猿—钱多话少死的早
 程序员的样子
程序员的样子
中美印日四国程序员比较
中美印日四国程序员比较
每天工作4小时的程序员
每天工作4小时的程序员
我跳槽是因为他们的显示器更大
我跳槽是因为他们的显示器更大
亲爱的项目经理,我恨你
亲爱的项目经理,我恨你
什么才是优秀的用户界面设计
什么才是优秀的用户界面设计
代码女神横空出世
代码女神横空出世
程序员都该阅读的书
程序员都该阅读的书
为啥Android手机总会越用越慢?
为啥Android手机总会越用越慢?
看13位CEO、创始人和高管如何提高工作效率
看13位CEO、创始人和高管如何提高工作效率
Java 与 .NET 的平台发展之争
Java 与 .NET 的平台发展之争
程序员眼里IE浏览器是什么样的
程序员眼里IE浏览器是什么样的
鲜为人知的编程真相
鲜为人知的编程真相
2013年中国软件开发者薪资调查报告
2013年中国软件开发者薪资调查报告
2013年美国开发者薪资调查报告
2013年美国开发者薪资调查报告
一个程序员的时间管理
一个程序员的时间管理
Web开发者需具备的8个好习惯
Web开发者需具备的8个好习惯
那些性感的让人尖叫的程序员
那些性感的让人尖叫的程序员
软件开发程序错误异常ExceptionCopyright © 2009-2015 MyException 版权所有