Chinaunix首页 | 论坛 | 博客
  • 博客访问: 9137545
  • 博文数量: 1725
  • 博客积分: 12961
  • 博客等级: 上将
  • 技术积分: 19840
  • 用 户 组: 普通用户
  • 注册时间: 2009-01-09 11:25
个人简介

偷得浮生半桶水(半日闲), 好记性不如抄下来(烂笔头). 信息爆炸的时代, 学习是一项持续的工作.

文章分类

全部博文(1725)

文章存档

2024年(1)

2023年(26)

2022年(112)

2021年(217)

2020年(157)

2019年(192)

2018年(81)

2017年(78)

2016年(70)

2015年(52)

2014年(40)

2013年(51)

2012年(85)

2011年(45)

2010年(231)

2009年(287)

分类: LINUX

2010-04-28 17:44:29

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

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

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

具体实现步骤如下:

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

Java代码
  1. package com.cmcc.demo;  
  2.   
  3.    
  4.   
  5. import com.cmcc.demo.ITaskCallback;  
  6.   
  7.    
  8.   
  9. interface ITaskBinder {  
  10.   
  11.       
  12.   
  13.     boolean isTaskRunning();  
  14.   
  15.           
  16.   
  17.     void stopRunningTask();      
  18.   
  19.       
  20.   
  21.     void registerCallback(ITaskCallback cb);      
  22.   
  23.      
  24.   
  25.     void unregisterCallback(ITaskCallback cb);  
  26.   
  27. }  


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

Java代码
  1. package com.cmcc.demo;  
  2.   
  3.    
  4.   
  5. interface ITaskCallback {  
  6.   
  7.     void actionPerformed(int actionId);  
  8.   
  9. }  


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

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

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

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

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


在MyActivity.java中ITaskCallback.aidl接口实现:

Java代码
  1. private ITaskCallback mCallback = new ITaskCallback.Stub() {  
  2.   
  3.         public void actionPerformed(int id) {  
  4.   
  5.            //TODO  
  6.   
  7.             printf("callback id=" + id);  
  8.   
  9.         }  
  10.   
  11. };  

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

Java代码
  1. public IBinder onBind(Intent t) {  
  2.   
  3.     printf("service on bind");  
  4.   
  5.     return mBinder;  


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

5、在服务器端回调客户端的函数. 前提是当客户端获取的IBinder接口的时候,要去注册回调函数, 只有这样, 服务器端才知道该调用那些函数在:MyService.java中:
Java代码
  1. void callback(int val) {  
  2.   
  3.     final int N = mCallbacks.beginBroadcast();  
  4.   
  5.     for (int i=0; i
  6.   
  7.         try {  
  8.   
  9.             mCallbacks.getBroadcastItem(i).actionPerformed(val);  
  10.   
  11.         } catch (RemoteException e) {  
  12.   
  13.             // The RemoteCallbackList will take care of removing  
  14.   
  15.             // the dead object for us.  
  16.   
  17.         }  
  18.   
  19.     }  
  20.   
  21.     mCallbacks.finishBroadcast();  
阅读(2760) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~