AIDL实现不同应用之间跨进程通讯及传递与返回各种数据类型和远程接口回调
2017-11-08 18:46
696 查看
含义: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类:
aidl文件:
注意事项:
1、客户端使用时必须要完整拷贝服务端的包及包下的相关AIDL文件和aidl文件中引用到的相关对象接口等java文件
2、对于aidl文件中用到的对象必须要进行序列化
如代码:
3、传递数组、对象等要用关键字(in,inout)
4、客户端远程接口回调用完一定要释放(unregister)掉,确保clinet端和server端的远程回调接口是一样的,否则会造成内存泄露拿不到数据
客户端目录结构:
关键代码片段:
源码点击下载
为什么要有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进程间传递复杂数据类型—AIDL传递其他AIDL接口
- 进程之间通讯:M_COPYDATA消息来实现两个进程之间传递数据.
- Android学习笔记_23_服务Service之AIDL和远程服务实现进程通信以及进程间传递自定义类型参数
- Android:使用AIDL实现进程间传递复杂数据类型
- 阿里RAP+fiddler实现app原生应用的cgi数据mock----- (二)添加mock规则,随机返回4中类型(不同长度)的数据
- AIDL进程间传递复杂数据类型—AIDL传递android.os.Parcelable接口
- Android学习笔记_23_服务Service之AIDL和远程服务实现进程通信以及进程间传递自定义类型参数
- Android开发中实现跨进程通讯的AIDL接口
- 如果在C#用WM_COPYDATA消息来实现两个进程之间传递数据
- AIDL-AndRoid接口描述语言实现跨进程通讯
- Ex3.10 不同Activity之间的数据传递——Bundle对象的实现
- Android应用中通过AIDL机制实现进程间的通讯实例
- 用WM_COPYDATA消息来实现两个进程之间传递数据
- 不同Activity之间的数据传递--Bundle对象的实现
- Android应用中通过AIDL机制实现进程间的通讯实例
- 使用AIDL实现进程间的通信之复杂类型传递
- [读书摘记]不同Activity之间的数据传递--Bundle对像的实现
- 如何在C#用WM_COPYDATA消息来实现两个进程之间传递数据
- [转]如何在C#用WM_COPYDATA消息来实现两个进程之间传递数据
- Android应用中通过AIDL机制实现进程间的通讯实例