Android,每个应用程序都有自己的进程,当需要在不同的进程之间传递对象时,该如何实现呢?

显然,Java中是不支持跨进程内存共享的。因此要传递对象,需要把对象解析成操作系统能够理解的数据格式,以达到跨界对象访问的目的。JavaEE中,采用RMI通过序列化传递对象。

Android,AIDL(AndroidInterfaceDefinitionLanguage:接口定义语言)方式实现。


AIDL是一种接口定义语言,用于约束两个进程间的通讯规则,供编译器生成代码,实现Android设备上的两个进程间通信(IPC)由于进程之间的通信信息需要双向转换,所以android采用代理类在背后实现了信息的双向转换,代理类由android编译器生成,对开发人员来说是透明的。


具体实现

假设A应用需要与B应用进行通信,调用B应用中的download(Stringpath)方法,B应用以Service方式向A应用提供服务。需要下面四个步骤:

1B应用中创建*.aidl文件aidl文件的定义和接口的定义很相类,如:在com.alex.aidl包下创建IDownloadService.aidl文件,内容如下:

package com.alex.aidl;interface IDownloadService {void download(String path);}

当完成aidl文件创建后,eclipse会自动在项目的gen目录中同步生成IDownloadService.java接口文件。接口文件中生成一个Stub的抽象类,里面包括aidl定义的方法,还包括一些其它辅助方法。值得关注的是asInterface(IBinderiBinder),它返回接口类型的实例,对于远程服务调用,远程服务返回给客户端的对象为代理对象,客户端在onServiceConnected(ComponentNamename,IBinderservice)方法引用该对象时不能直接强转成接口类型的实例,而应该使用asInterface(IBinderiBinder)进行类型转换。


2B应用中实现aidl文件生成的接口(本例是IDownloadService),但并非直接实现接口,而是通过继承接口的Stub来实现(Stub抽象类内部实现了aidl接口),并且实现接口方法的代码。内容如下:

public class ServiceBinder extends IDownloadService.Stub {@Overridepublic void download(String path) throws RemoteException {Log.i("DownloadService", path);}}

3B应用中创建一个Service(服务),在服务的onBind(Intentintent)方法中返回实现了aidl接口的对象(本例是ServiceBinder)。内容如下:

public class DownloadService extends Service {private ServiceBinder serviceBinder = new ServiceBinder();@Overridepublic IBinder onBind(Intent intent) {return serviceBinder;}public class ServiceBinder extends IDownloadService.Stub {@Overridepublic void download(String path) throws RemoteException {Log.i("DownloadService", path);}}}


其他应用可以通过隐式意图访问服务,意图的动作可以自定义,AndroidManifest.xml配置代码如下:

<service android:name=".DownloadService" ><intent-filter><action android:name="com.alex.process.aidl.DownloadService" /></intent-filter></service>


4B应用中aidl文件所在package连同aidl文件一起拷贝到客户端A应用eclipse会自动在A应用的gen目录中为aidl文件同步生成IDownloadService.java接口文件,接下来就可以在A应用中实现与B应用通信,代码如下:

public class ClientActivity extends Activity {private IDownloadService downloadService;@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.main);this.bindService(new Intent("com.alex.process.aidl.DownloadService"),                                     this.serviceConnection, BIND_AUTO_CREATE);//绑定到服务}@Overrideprotected void onDestroy() {super.onDestroy();this.unbindService(serviceConnection);//解除服务}private ServiceConnection serviceConnection = new ServiceConnection() {@Overridepublic void onServiceConnected(ComponentName name, IBinder service) {downloadService = IDownloadService.Stub.asInterface(service);try {downloadService.download("http://www.test.com/...");} catch (RemoteException e) {Log.e("ClientActivity", e.toString());}}@Overridepublic void onServiceDisconnected(ComponentName name) {downloadService = null;}};}


更多相关文章

  1. NPM 和webpack 的基础使用
  2. 【阿里云镜像】使用阿里巴巴DNS镜像源——DNS配置教程
  3. android 反编
  4. Android(安卓)应用程序快速启动的秘诀
  5. Android(安卓)序列化之parcelable的简单使用
  6. 初始Android
  7. 2010-03-02 传智播客—Android(四)数据存储之五网络
  8. Android(安卓)Studio(七)Android(安卓)Studio 如何Debug
  9. Android应用程序注册广播接收器(registerReceiver)的过程分析

随机推荐

  1. find ./ -name "hardware.*" 查找文件
  2. 分享Android微信红包插件
  3. Android 判断当前程序是否在前台运行
  4. Error:Could not determine the dependen
  5. Android 多线程1
  6. Android studio应用程序设计——简单的学
  7. AndroidStudio出现tools:replace="androi
  8. android:clipChildren="false"
  9. js 判断iPhone|iPad|iPod|iOS|Android客
  10. FloatingActionButton 浮动按钮