AIDL实现应用进程间的通信。
来源:互联网 发布:装修软件手机版 编辑:程序博客网 时间:2024/05/22 01:58
AIDL是android中进程间通讯的一种实现方式。AIDL(Android Interface Definition Language)是一种接口定义语言,编译器通过*.aidl文件的描述信息生成符合通信协议的Java代码,我们无需自己去写这段繁杂的代码,只需要在需要的时候调用即可,通过这种方式我们就可以完成进程间的通信工作。
这种方式很像Service通过接口实现参数传递以及与Activity之间进行交互的实现方式。
直接上DEMO:
1、建立服务端工程。就是一个aidl接口和一个Service类。aidl接口中有一个接口方法。
aidl接口的创建是在工程目录下new一个Text File 并加上 .aidl后缀名完成的,这里需要注意的是aidl文件名需要与定义的接口名保持一致。
建好aidl接口后,可以看到gen目录下自动为我们生成了IName.java类,里面代码如下如下。
/* * This file is auto-generated. DO NOT MODIFY. * Original file: D:\\android\\2015_11\\aidl_service\\src\\com\\aidl_service\\IName.aidl */package com.aidl_service;public interface IName extends android.os.IInterface{/** Local-side IPC implementation stub class. */public static abstract class Stub extends android.os.Binder implements com.aidl_service.IName{private static final java.lang.String DESCRIPTOR = "com.aidl_service.IName";/** Construct the stub at attach it to the interface. */public Stub(){this.attachInterface(this, DESCRIPTOR);}/** * Cast an IBinder object into an com.aidl_service.IName interface, * generating a proxy if needed. */public static com.aidl_service.IName asInterface(android.os.IBinder obj){if ((obj==null)) {return null;}android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);if (((iin!=null)&&(iin instanceof com.aidl_service.IName))) {return ((com.aidl_service.IName)iin);}return new com.aidl_service.IName.Stub.Proxy(obj);}@Override public android.os.IBinder asBinder(){return this;}@Override public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException{switch (code){case INTERFACE_TRANSACTION:{reply.writeString(DESCRIPTOR);return true;}case TRANSACTION_showName:{data.enforceInterface(DESCRIPTOR);java.lang.String _arg0;_arg0 = data.readString();this.showName(_arg0);reply.writeNoException();return true;}}return super.onTransact(code, data, reply, flags);}private static class Proxy implements com.aidl_service.IName{private android.os.IBinder mRemote;Proxy(android.os.IBinder remote){mRemote = remote;}@Override public android.os.IBinder asBinder(){return mRemote;}public java.lang.String getInterfaceDescriptor(){return DESCRIPTOR;}@Override public void showName(java.lang.String name) throws android.os.RemoteException{android.os.Parcel _data = android.os.Parcel.obtain();android.os.Parcel _reply = android.os.Parcel.obtain();try {_data.writeInterfaceToken(DESCRIPTOR);_data.writeString(name);mRemote.transact(Stub.TRANSACTION_showName, _data, _reply, 0);_reply.readException();}finally {_reply.recycle();_data.recycle();}}}static final int TRANSACTION_showName = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);}public void showName(java.lang.String name) throws android.os.RemoteException;}不用看懂,只需要知道IName接口中的抽象内部类Stub继承android.os.Binder类并实现IPerson接口,比较重要的方法是asInterface(IBinder)方法,该方法会将IBinder类型的对象转换成IName类型,必要的时候生成一个代理对象返回结果。
接下来就是service了:
public class AIDLService extends Service {private Handler mHandler = new Handler();public IName.Stub stubBinder = new IName.Stub() {@Overridepublic void showName(String name) throws RemoteException {mHandler.post(new Runnable() {@Overridepublic void run() {Toast.makeText(AIDLService.this, "aidl中的接口方法", Toast.LENGTH_SHORT).show();}});}};@Overridepublic IBinder onBind(Intent intent) {return stubBinder;}}里面就是实现接口方法,让后在OnBind方法中返回该接口对象。最后需要到AndroidManifest.xml中做一些配置工作
<service android:name="com.aidl_service.AIDLService"> <intent-filter> <action android:name="com.aidl_service.AIDLService"/> </intent-filter> </service>这样就完成了。
接下来我们看看客户端,客服端需要做什么呢?就是将接口暴露出来,直接调用接口方法达到数据的共享。
第一步直接将aidl文件连包名一起复制到客服端路径下。不需要服务,所以这里已将同包下的服务类删掉了。拷贝过来后也会自动在gen目录下生成一个IName.java类,该类的内容与在服务端生成该类的内容一样。
最后看看MainActivity里做了什么?
public class MainActivity extends Activity {private Button mBtn;private IName INameBinder;private ServiceConnection conn = new ServiceConnection() {@Overridepublic void onServiceDisconnected(ComponentName name) {if(INameBinder != null)INameBinder = null;}@Overridepublic void onServiceConnected(ComponentName name, IBinder service) {INameBinder = IName.Stub.asInterface(service); //转化为对应aidl接口对象}}; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mBtn = (Button) findViewById(R.id.aidl_btn); Intent intent = new Intent("com.aidl_service.AIDLService"); bindService(intent, conn, BIND_AUTO_CREATE); mBtn.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {try {INameBinder.showName("123");} catch (RemoteException e) {e.printStackTrace();}}}); } @Override protected void onDestroy() { super.onDestroy(); if(conn != null){ unbindService(conn); } }}里面就是启动服务,并在ServiceConnection里面得到了aidl接口的实列,也就是IBinder的实列。
@Overridepublic void onServiceConnected(ComponentName name, IBinder service) {INameBinder = IName.Stub.asInterface(service); //转化为对应aidl接口对象}通过该实列来实现对服务端里进程间的通信。
在测试运行的时候先启动服务端。在启动客户端MainActivity点击按钮调用接口方法弹出对话框。
最后上效果图:
注意在定义aidl文件时,接口方法中的参数和返回值若是int ,string等基本数据类型是不需要import导入的。若是实现其他的接口或者是自定义序列号对象类型则需要import导入。
- AIDL实现应用进程间的通信。
- 使用AIDL实现进程间的通信
- 使用AIDL实现进程间的通信
- 使用AIDL实现进程间的通信
- 使用AIDL实现进程间的通信
- 使用AIDL实现进程间的通信
- 使用AIDL实现进程间的通信
- 使用AIDL实现进程间的通信
- 使用AIDL实现进程间的通信
- 使用AIDL实现进程间的通信
- 使用AIDL实现进程间的通信
- 使用AIDL实现进程间的通信
- 使用AIDL实现进程间的通信
- 使用AIDL实现进程间的通信
- 使用AIDL实现进程间的通信
- 使用AIDL实现进程间的通信
- 使用AIDL实现进程间的通信
- 使用AIDL实现进程间的通信
- java基础1
- 剪刀石头布 (上 下) 注意:合成图片,内容自理
- 定时进度条 进度100%以后可以切换图片
- Android快速SDK(6)本地图形库CopyView
- 【TED】处乱不惊-Daniel Levitin
- AIDL实现应用进程间的通信。
- Kernel. EXPORT_SYMBOL解析
- 多维数组 对应的产品数量和价格相加
- 小技巧8-iOS 使用Global BreakPoint(全局断点)快速定位Bug
- C++ 读取bmp内容
- 悲观锁与乐观锁
- Spark stage切分和提交
- android中aidl的简单使用
- 【iOS开发】总结