Android:不使用AIDL实现进程间的通信
来源:互联网 发布:怎么设计淘宝店 编辑:程序博客网 时间:2024/06/04 19:06
在上一篇:Android Studio中实现AIDL
中我们已经学会使用AIDL的简单操作,那么现在来实现一下在不依赖AIDL的前提下,实现进程间的通信。
1、Binder:
实现进程间的相互通信。
2、Service:
一个独立的进程。在Android中我们要实现进程间的通信,就必须要用到Service,那么我么就从这里开始分析:
@Overridepublic IBinder onBind(Intent intent) { Logger.d("onBind"); return mBinder;}在实onBind(Intent intent)方法中,我们必须要返回一个IBinder对象,如果不返回,则不能够正常通信:
IBinder
android.os.IBinderKnown Indirect SubclassesBinderBase class for a remotable object, the core part of a lightweight remote procedure call mechanism defined byIBinder
. 其子类就是一个Binder,
那么我们在来看通过AIDL实现进程通信时的方法:
这里使用:ICalculatorAIDL.aidl 为例
分析代码:
private final ICalculatorAIDL.Stub mBinder = new ICalculatorAIDL.Stub() { @Override public String aidlTest(String msg) throws RemoteException { return "经过AIDL测试后:"+msg; }};onBinder()方法中的mBinder由这里获取,那么我们看看ICalculatorAIDL.Stub :
/** * Local-side IPC implementation stub class. */public static abstract class Stub extends android.os.Binder implements com.gr.aidl.ICalculatorAIDL {Stub实质就是一个Binder对象的子类,那么我们可以设想创建一个类来继承Binder类,来代替Stub;
private final MyBinder mBinder = new MyBinder();private class MyBinder extends Binder { /** * 要实现通信,必须要从写该方法 * @param code 服务器通过该指令来区分所要执行的方法 * @param data 客户端传入的数据 * @param reply 服务端返回的数据 * @param flags 是否有返回值,0为有,1为没有 * @return * @throws RemoteException */ @Override protected boolean onTransact(int code, Parcel data, Parcel reply, int flags) throws RemoteException { return super.onTransact(code, data, reply, flags); }
现在来分析一下AIDL中onTransact()方法中到底做了什么。
// ICalculatorAIDL.aidlpackage com.gr.aidl;// Declare any non-default types here with import statementsinterface ICalculatorAIDL { String aidlTest(String msg);}
@Overridepublic 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_aidlTest: { //与客户端的writeInterfaceToken对用,标识远程服务的名称 data.enforceInterface(DESCRIPTOR); //创建String对象 java.lang.String _arg0; //从data中读取String数据,因为我传入的是一个String _arg0 = data.readString(); //调用aidlTest()方法,并传入对应参数(在CalculatorAIDLService中已被实现) java.lang.String _result = this.aidlTest(_arg0); reply.writeNoException(); //写入执行结果,返回给客户端 reply.writeString(_result); return true; } } return super.onTransact(code, data, reply, flags);}ok,既然这样,我们也这样实现:
private class MyBinder extends Binder { public static final String DESCRIPTOR = "CalculatorAIDLService"; public static final int TAG = 0x11;//这里是自己定义的,方便区别 @Override protected boolean onTransact(int code, Parcel data, Parcel reply, int flags) throws RemoteException { switch (code) { case TAG: data.enforceInterface(DESCRIPTOR); String param = data.readString(); String result = "这里是使用不依赖AIDL加工的:"+param; //修改文字格式 reply.writeNoException(); reply.writeString(result); return true; } return super.onTransact(code, data, reply, flags); }}
3、Client:
客户端与服务端的连接是通过ServieceConnection进行通信的:
private ServiceConnection mServiceConnection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName componentName, IBinder iBinder) {如果连接成功,则调用onServiceConnection()方法,并传递一个IBinder对象回来。这里的IBinder就是我们所要的Binder。在上面代码中我们在之前使用AIDL方法的时候,调用了:// mIcalculatorAIDL = ICalculatorAIDL.Stub.asInterface(iBinder); mBinder = iBinder;Logger.d("onServiceConnected"); } @Override public void onServiceDisconnected(ComponentName componentName) { Logger.d("onServiceDisconnected"); } };
// mIcalculatorAIDL = ICalculatorAIDL.Stub.asInterface(iBinder);
通过观察,实质上是调用了:return new com.gr.aidl.ICalculatorAIDL.Stub.Proxy(obj);继续:
private static class Proxy implements com.gr.aidl.ICalculatorAIDL { 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 java.lang.String aidlTest(java.lang.String msg) throws android.os.RemoteException { android.os.Parcel _data = android.os.Parcel.obtain(); android.os.Parcel _reply = android.os.Parcel.obtain(); java.lang.String _result; try { _data.writeInterfaceToken(DESCRIPTOR); _data.writeString(msg); //传入的参数值 mRemote.transact(Stub.TRANSACTION_aidlTest, _data, _reply, 0); //调用IBinder中的transact这里的Proxy对我们的接口方法进行了实现:_result = _reply.readString(); } finally { _reply.recycle(); _data.recycle(); } return _result; } } static final int TRANSACTION_aidlTest = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);}_reply.readException();
@Override public java.lang.String aidlTest(java.lang.String msg) throws android.os.RemoteException {}现在客户端上实现:
//onClick 事件public void sendMessage(View view) { Logger.d("sendMessage"); if (mBinder == null) { return; } Parcel _data = Parcel.obtain(); Parcel _reply = Parcel.obtain(); String _result = ""; try { _data.writeInterfaceToken(CalculatorAIDLService.DESCRIPTOR); _data.writeString(mMessage);ok,现在运行测试:_data, _reply, 0);//注意:这里不能直接使用MyBinder类的mBinder.onTransact()方法,如果在这里调用的话,得不到准确结果 /** * Default implementation rewinds the parcels and calls onTransact. On * the remote side, transact calls into the binder to do the IPC. */ /** public final boolean transact(int code, Parcel data, Parcel reply, * int flags) throws RemoteException { * if (false) Log.v("Binder", "Transact: " + code + " to " + this); * if (data != null) { * data.setDataPosition(0); * } * boolean r = onTransact(code, data, reply, flags); * if (reply != null) { * reply.setDataPosition(0); * } * return r; * } */ mBinder.transact(CalculatorAIDLService.TAG,_result = _reply.readString(); Toast.makeText(this, _result, Toast.LENGTH_LONG).show(); } catch (Exception e) { e.printStackTrace(); } finally { _reply.recycle(); _data.recycle(); }}_reply.readException();
源码下载
1 0
- Android:不使用AIDL实现进程间的通信
- android 使用AIDL实现进程间通信
- Android使用AIDL实现进程间通信
- Android使用AIDL实现进程间通信
- Android使用AIDL实现进程间通信
- Android使用AIDL实现进程间通信
- Android使用AIDL实现进程间通信
- Android使用AIDL实现进程间通信
- Android实现进程间通信aidl的使用
- android使用aidl实现进程间通信的实例
- Android基础--使用AIDL实现进程间的通信
- Android AIDL使用详解 实现进程间的通信
- android使用AIDL实现进程间的通信
- android AIDL实现进程间的通信
- AIDL实现Android进程间的通信
- 使用AIDL实现进程间的通信
- 使用AIDL实现进程间的通信
- 使用AIDL实现进程间的通信
- java记住密码
- 2月20号 点击按钮打印名字
- Java - 正则表达式匹配模式
- JSON 转换为java 类时出现的错误,
- WAPI协议完整性测试解析系列(之一)WAI子类型的协议完整性测试
- Android:不使用AIDL实现进程间的通信
- imx led service
- [J2EE]java web项目中调用word转html命令行工具
- 国内外有名的计算机视觉团队汇总
- Android Zygote系统进程启动过程分析(Android N)
- Zshell
- Hibernate入门
- [转]解决 Excel 打开 UTF-8 编码 CSV 文件乱码的 BUG
- 非常好的在网页中显示pdf的方法