AIDL实现不同应用之间跨进程通讯及传递与返回各种数据类型和远程接口回调
来源:互联网 发布:英语书籍阅读软件 编辑:程序博客网 时间:2024/05/04 23:00
含义:AIDL(Android Interface Definition Language),是android接口定义语言,这种语言定义了一个客户端和服务器通讯接口的一个标准、规范。
为什么要有AIDL?
我们都知道android中的四大组件Activity,Broadcast,Content Provider,Service,前面我们应该都接触过除了Service的其他三个组件的进程间通讯的例子,比如:一个应用可以通过显示意图启动另外一个Activity,一个应用发送一个广播,然后被其他应用所接受,一个应用对外提供一个Content Provider,然后其他应用使用ContentResolver获取它提供的数据。这些都是进程间通讯的例子(通常情况下每个应用运行在一个独立的Linux进程中),那么Service这个组件也同样也可以实现垮进程通讯
本人工作项目做得是封闭式车载导航系统,各个应用进行数据交换是很常见的事,例如launcher是需要去拿蓝牙,收音或者多媒体等数据然后作相应操作,如果在这之间用广播作数据通讯显得太low并且也麻烦,所以一般都采用aidl这种方式进行数据交换,当然了 也可以在底层framework应用框架层写一个接口服务回调上层,这样上层每一个应用都可以进行监听获取数据,太多理论性的东西这里不去说,这边只做aidl的使用说明总结:
server端目录结构:
关键代码片段
服务端service类:
public class BTManagerService extends Service implements TimeCallBack { private IBinder myBinder = new BTBinder(); private IBinder mClientBinder = null; class BTDeathRecipient implements DeathRecipient { @Override public void binderDied() { System.out.println("---binderDied()--- "); } } private class BTBinder extends IBTService.Stub { @Override public void setPinCode(String pincode) throws RemoteException { System.out.println("---setPinCode()--- " + pincode); } @Override public void setClientBinder(IBinder client) throws RemoteException { System.out.println("---setClientBinder()--- "); mClientBinder = client; mClientBinder.linkToDeath(new BTDeathRecipient(), 0); } @Override public void setDeviceInfo(DeviceInfo deviceInfo) throws RemoteException { System.out.println("---setDeviceInfo()--- " + deviceInfo.mDeviceName); } @Override public void onRequestAudioFocus() throws RemoteException { System.out.println("---onRequestAudioFocus()--- "); } @Override public boolean isBTOpen() throws RemoteException { return false; } @Override public int getA2dpStatus() throws RemoteException { return 0; } @Override public String getLastTelephone() throws RemoteException { return "asir"; } @Override public PlayStatusInfo getPlayStatusInfo() throws RemoteException { PlayStatusInfo playStatusInfo = new PlayStatusInfo(); playStatusInfo.mMediaLength = 666; return playStatusInfo; } @Override public MediaID3Info getMediaID3Info() throws RemoteException { MediaID3Info mediaID3Info = new MediaID3Info(); mediaID3Info.mMediaTitle = "asir"; return mediaID3Info; } @Override public PhonebookInfo getCurrentRecordInfo() throws RemoteException { PhonebookInfo phonebookInfo = new PhonebookInfo(); phonebookInfo.mTelephone = "563209751@qq.com"; return phonebookInfo; } @Override public List<DeviceInfo> getDeviceInfoList() throws RemoteException { List<DeviceInfo> list = new ArrayList<DeviceInfo>(); DeviceInfo d1 = new DeviceInfo(); d1.mDeviceStatus = 1; DeviceInfo d2 = new DeviceInfo(); d2.mDeviceStatus = 2; DeviceInfo d3 = new DeviceInfo(); d3.mDeviceStatus = 3; list.add(d1); list.add(d2); list.add(d3); return list; } @Override public List<PhonebookInfo> getPhonebookList() throws RemoteException { List<PhonebookInfo> list = new ArrayList<PhonebookInfo>(); PhonebookInfo f1 = new PhonebookInfo(); f1.mTelephone = "1"; PhonebookInfo f2 = new PhonebookInfo(); f2.mTelephone = "2"; PhonebookInfo f3 = new PhonebookInfo(); f3.mTelephone = "3"; list.add(f1); list.add(f2); list.add(f3); return list; } @Override public int onGetMicGainEvent(int[] configs) throws RemoteException { for (int i : configs) { System.out.println("-s-" + i); } return 0; } @Override public int onSetMicGainEvent(String[] configs) throws RemoteException { for (String str : configs) { System.out.println("-s-" + str); } return 0; } @Override public void registerCallback(IMediaPlayerListener listener) throws RemoteException { System.out.println("---registerCallback()---"); if (null != listener && null == mListener) { MainActivity.getMainActivity().setTimeCallBack(BTManagerService.this); mListener = listener; mRemoteCallbackList.register(mListener); } } @Override public void unregisterCallback(IMediaPlayerListener listener) throws RemoteException { System.out.println("---unregisterCallback()---"); mRemoteCallbackList.unregister(mListener); mListener = null; } } private RemoteCallbackList<IMediaPlayerListener> mRemoteCallbackList = new RemoteCallbackList<IMediaPlayerListener>(); private IMediaPlayerListener mListener = null; @Override /** * 媒体播放时间回调 */ public void timeChangeCallBack(String poi, String duration) { try { mListener.playTimeChangeListener(poi, duration); } catch (Exception e) { e.printStackTrace(); } } @Override public void onCreate() { super.onCreate(); } @Override public int onStartCommand(Intent intent, int flags, int startId) { return super.onStartCommand(intent, flags, startId); } @Override public IBinder onBind(Intent intent) { return myBinder; } @Override public boolean onUnbind(Intent intent) { return super.onUnbind(intent); } @Override public void onDestroy() { super.onDestroy(); }}
aidl文件:
package com.asir.aidlserver;import java.util.List;import com.asir.aidlserver.DeviceInfo;import com.asir.aidlserver.PhonebookInfo;import com.asir.aidlserver.MediaID3Info;import com.asir.aidlserver.PlayStatusInfo;import com.asir.aidlserver.IMediaPlayerListener;interface IBTService { void setPinCode(String pincode); void setClientBinder(IBinder client); void setDeviceInfo(in DeviceInfo deviceInfo); void onRequestAudioFocus(); boolean isBTOpen(); int getA2dpStatus(); String getLastTelephone(); PlayStatusInfo getPlayStatusInfo(); MediaID3Info getMediaID3Info(); PhonebookInfo getCurrentRecordInfo(); List<DeviceInfo> getDeviceInfoList(); List<PhonebookInfo> getPhonebookList(); int onGetMicGainEvent(inout int[] configs); int onSetMicGainEvent(inout String[] configs); void registerCallback(IMediaPlayerListener listener); void unregisterCallback(IMediaPlayerListener listener);}
注意事项:
1、客户端使用时必须要完整拷贝服务端的包及包下的相关AIDL文件和aidl文件中引用到的相关对象接口等java文件
2、对于aidl文件中用到的对象必须要进行序列化
如代码:
public class PhonebookInfo implements Parcelable { public int mType; public String mTelephone = null; public String mUserName = null; public PhonebookInfo() { mType = 0; mTelephone = new String(); mUserName = new String(); } private PhonebookInfo(Parcel source) { mType = source.readInt(); mTelephone = source.readString(); mUserName = source.readString(); } @Override public int describeContents() { // TODO Auto-generated method stub return 0; } @Override public void writeToParcel(Parcel dest, int flags) { dest.writeInt(mType); dest.writeString(mTelephone); dest.writeString(mUserName); } public static final Parcelable.Creator<PhonebookInfo> CREATOR = new Parcelable.Creator<PhonebookInfo>() { @Override public PhonebookInfo createFromParcel(Parcel source) { return new PhonebookInfo(source); } @Override public PhonebookInfo[] newArray(int size) { return new PhonebookInfo[size]; } };}
3、传递数组、对象等要用关键字(in,inout)
4、客户端远程接口回调用完一定要释放(unregister)掉,确保clinet端和server端的远程回调接口是一样的,否则会造成内存泄露拿不到数据
客户端目录结构:
关键代码片段:
private final class BTConnection implements ServiceConnection { @Override public void onServiceConnected(ComponentName name, IBinder service) { mBTService = IBTService.Stub.asInterface(service); try { if (null == mIM) { mIM = new IMediaPlayerListener.Stub() { @Override public void playTimeChangeListener(String poi, String duration) throws RemoteException { System.out.println(poi + " --- " + duration); } }; mBTService.registerCallback(mIM); } } catch (RemoteException e) { e.printStackTrace(); } } @Override public void onServiceDisconnected(ComponentName name) { mBTService = null; } } private void onBindService() { if (mBTService == null && mBTConnection != null) { Intent intent = new Intent("com.asir.aidlserver.BTManagerService"); MainActivity.this.bindService(intent, mBTConnection, BIND_AUTO_CREATE); } } private void onUnbindService() { if (mBTService != null && mBTConnection != null) { MainActivity.this.unbindService(mBTConnection); try { mBTService.unregisterCallback(mIM); // 此处一定要进行资源释放,否则重新加载时会造成内存泄露 } catch (RemoteException e) { e.printStackTrace(); } } mBTService = null; mBTConnection = null; }
源码点击下载
- AIDL实现不同应用之间跨进程通讯及传递与返回各种数据类型和远程接口回调
- Android开发中实现跨进程通讯的AIDL接口
- Android开发中实现跨进程通讯的AIDL接口
- AIDL-AndRoid接口描述语言实现跨进程通讯
- Android开发中实现跨进程通讯的AIDL接口
- AIDL跨进程通讯访问远程服务
- Android的跨进程通信介绍----------------aidl,传递复杂对象以及Server和Clicent之间的回调
- Android AIDL跨进程通讯
- android AIDL,跨进程通讯
- Service基本入门及AIDL跨进程通讯
- android使用AIDL实现跨进程通讯(IPC)
- android使用AIDL实现跨进程通讯(IPC)
- 示例:Android使用AIDL实现跨进程通讯(IPC)
- android中的跨进程通信的实现(一)——远程调用过程和aidl
- android中的跨进程通信的实现——远程调用过程和aidl(转)
- android中的跨进程通信的实现(一)——远程调用过程和aidl
- android中的跨进程通信的实现(一)——远程调用过程和aidl
- Android中的跨进程通信的实现——远程调用过程和aidl
- jdbcTemplate注入过程
- Hbase官方手册-快速入门
- 怎样理解阻塞非阻塞与同步异步的区别?
- Java读书笔记——04 输入输出
- disconf启动流程
- AIDL实现不同应用之间跨进程通讯及传递与返回各种数据类型和远程接口回调
- 【转】关于HTTP协议,一篇就够了
- hdu5714
- python 中的selenium模块使用方法
- ansible2.4学习(安装部署)
- Python学习笔记(四)字符串
- 关于安装Homebrew
- Android中用inteng启用不同应用中的活动
- 逗比日记_参考的小习惯