Android AIDL的使用(配源码)

news/2025/2/21 16:56:05/

零、完整源代码

链接: https://github.com/jx0260/TestGradle

一、创建AIDL文件

// IShopAidlInterface.aidl
package com.example.testgradle;// Declare any non-default types here with import statementsinterface IShopAidlInterface {String getProductInfo(int productNo);void buyProduct1(int productNo, String address);}

二、Make Project 生成Binder工具类

AndroidStudio make project
路径为:
在这里插入图片描述
生成代码如下(下一篇文章会分析这些生成的代码):

/** This file is auto-generated.  DO NOT MODIFY.*/
package com.example.testgradle;
// Declare any non-default types here with import statementspublic interface IShopAidlInterface extends android.os.IInterface
{/** Default implementation for IShopAidlInterface. */public static class Default implements com.example.testgradle.IShopAidlInterface{@Override public java.lang.String getProductInfo(int productNo) throws android.os.RemoteException{return null;}@Override public void buyProduct1(int productNo, java.lang.String address) throws android.os.RemoteException{}@Overridepublic android.os.IBinder asBinder() {return null;}}/** Local-side IPC implementation stub class. */public static abstract class Stub extends android.os.Binder implements com.example.testgradle.IShopAidlInterface{private static final java.lang.String DESCRIPTOR = "com.example.testgradle.IShopAidlInterface";/** Construct the stub at attach it to the interface. */public Stub(){this.attachInterface(this, DESCRIPTOR);}/*** Cast an IBinder object into an com.example.testgradle.IShopAidlInterface interface,* generating a proxy if needed.*/public static com.example.testgradle.IShopAidlInterface asInterface(android.os.IBinder obj){if ((obj==null)) {return null;}android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);if (((iin!=null)&&(iin instanceof com.example.testgradle.IShopAidlInterface))) {return ((com.example.testgradle.IShopAidlInterface)iin);}return new com.example.testgradle.IShopAidlInterface.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{java.lang.String descriptor = DESCRIPTOR;switch (code){case INTERFACE_TRANSACTION:{reply.writeString(descriptor);return true;}case TRANSACTION_getProductInfo:{data.enforceInterface(descriptor);int _arg0;_arg0 = data.readInt();java.lang.String _result = this.getProductInfo(_arg0);reply.writeNoException();reply.writeString(_result);return true;}case TRANSACTION_buyProduct1:{data.enforceInterface(descriptor);int _arg0;_arg0 = data.readInt();java.lang.String _arg1;_arg1 = data.readString();this.buyProduct1(_arg0, _arg1);reply.writeNoException();return true;}default:{return super.onTransact(code, data, reply, flags);}}}private static class Proxy implements com.example.testgradle.IShopAidlInterface{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 getProductInfo(int productNo) 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.writeInt(productNo);boolean _status = mRemote.transact(Stub.TRANSACTION_getProductInfo, _data, _reply, 0);if (!_status && getDefaultImpl() != null) {return getDefaultImpl().getProductInfo(productNo);}_reply.readException();_result = _reply.readString();}finally {_reply.recycle();_data.recycle();}return _result;}@Override public void buyProduct1(int productNo, java.lang.String address) 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.writeInt(productNo);_data.writeString(address);boolean _status = mRemote.transact(Stub.TRANSACTION_buyProduct1, _data, _reply, 0);if (!_status && getDefaultImpl() != null) {getDefaultImpl().buyProduct1(productNo, address);return;}_reply.readException();}finally {_reply.recycle();_data.recycle();}}public static com.example.testgradle.IShopAidlInterface sDefaultImpl;}static final int TRANSACTION_getProductInfo = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);static final int TRANSACTION_buyProduct1 = (android.os.IBinder.FIRST_CALL_TRANSACTION + 1);public static boolean setDefaultImpl(com.example.testgradle.IShopAidlInterface impl) {// Only one user of this interface can use this function// at a time. This is a heuristic to detect if two different// users in the same process use this function.if (Stub.Proxy.sDefaultImpl != null) {throw new IllegalStateException("setDefaultImpl() called twice");}if (impl != null) {Stub.Proxy.sDefaultImpl = impl;return true;}return false;}public static com.example.testgradle.IShopAidlInterface getDefaultImpl() {return Stub.Proxy.sDefaultImpl;}}public java.lang.String getProductInfo(int productNo) throws android.os.RemoteException;public void buyProduct1(int productNo, java.lang.String address) throws android.os.RemoteException;
}

IShopAidlInterface这个生成的文件里面有 Stub类、Proxy类等,简单理解就是服务端(Stub)、客户端(proxy)它们为我们提供了跨进程通信的能力。为技术上的通信打通路径,唯一缺少的是业务方法的实现

三、编写服务端

3.1 实现服务端 Stub 业务

class Stub implements com.example.testgradle.IShopAidlInterface

AIDL为我们生成的Stub类,实现了 com.example.testgradle.IShopAidlInterface 接口,我们现在就实现他的业务方法:

private IShopAidlInterface.Stub mBinder = new IShopAidlInterface.Stub() {@Overridepublic String getProductInfo(int productNo) throws RemoteException {Log.i(TAG, "SERVER: receive productNo: " + productNo);return "the productNo is: " + productNo + ", productName is LEGO!";}@Overridepublic void buyProduct1(int productNo, String address) throws RemoteException {Log.i(TAG, "SERVER: receive productNo: " + productNo + ", address: " +address);Log.i(TAG, "YOU buy succeed!");}};

现在我们就实现好了,简单打印一些消息。有了服务端的Stub类,客户端怎么调用到它呢?
我们通过Android四大组件的Service,将这个服务端的Stub“传到”客户端,再在客户端进行调用:

3.2 定义服务端的Service

public class ShopService extends Service {private String TAG = "ShopService";public ShopService() {}private IShopAidlInterface.Stub mBinder = new IShopAidlInterface.Stub() {@Overridepublic String getProductInfo(int productNo) throws RemoteException {Log.i(TAG, "SERVER: receive productNo: " + productNo);return "the productNo is: " + productNo + ", productName is LEGO!";}@Overridepublic void buyProduct1(int productNo, String address) throws RemoteException {Log.i(TAG, "SERVER: receive productNo: " + productNo + ", address: " +address);Log.i(TAG, "YOU buy succeed!");}};@Overridepublic IBinder onBind(Intent intent) {return mBinder;}
}

我们在 onBind() 方法中,将Stub对象传出去。
manifest 文件配置一下:

<serviceandroid:name=".ShopService"android:enabled="true"android:exported="true"><intent-filter><action android:name="com.example.testgradle.ShopService"/></intent-filter>
</service>

(注意 exported=“true”,意味着允许让外部组件启动,我们要做跨进程调用,所以要允许客户端能访问此Service)

四、编写客户端

新建一个Application,创建一个Activity:
在Create() 方法中:

private IShopAidlInterface iShopAidlInterface;@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_client);Intent serviceIntent = new Intent("com.example.testgradle.ShopService");serviceIntent.setPackage("com.example.testgradle");bindService(serviceIntent, new ServiceConnection() {@Overridepublic void onServiceConnected(ComponentName name, IBinder service) {Log.i("ClientActivity", "onServiceConnected() service=" + service);iShopAidlInterface = IShopAidlInterface.Stub.asInterface(service);try {iShopAidlInterface.getProductInfo(1221);iShopAidlInterface.buyProduct1(9988, "大连市甘井子区");} catch (RemoteException e) {e.printStackTrace();}}@Overridepublic void onServiceDisconnected(ComponentName name) {}}, BIND_AUTO_CREATE);findViewById(R.id.btn_getInfo).setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {try {iShopAidlInterface.getProductInfo(1221);} catch (RemoteException e) {e.printStackTrace();}}});findViewById(R.id.btn_buy).setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {try {iShopAidlInterface.buyProduct1(9988, "大连市西岗区");} catch (RemoteException e) {e.printStackTrace();}}});
}

我们通过bindService,绑定到刚才在服务端定义的Service。在onServiceConnected()
回调中,将传过来的 IBinder 对象,使用 Stub.asInterface 转成 IShopAidlInterface 对象。再调用其中的业务方法。
由于我们是两个进程,所以此处的 使用 Stub.asInterface 转出的对象 就是一个 Proxy。

五、点按钮运行

打印日志:

com.example.testgradle I/ShopService: SERVER: receive productNo: 1221
com.example.testgradle I/ShopService: SERVER: receive productNo: 9988, address: 大连市西岗区
com.example.testgradle I/ShopService: YOU buy succeed!

下一篇文章,将详细描述,这中间发生了什么 及AIDL 与 Binder 的关系。


http://www.ppmy.cn/news/240897.html

相关文章

几款不错的golang应用包 持续更新中~~~

队列 1、hibiken/asynq 保证至少执行一次任务 任务调度 重试失败的任务 在工作进程崩溃时自动恢复任务 加权优先级队列 严格优先级队列 由于Redis中的写入速度很快&#xff0c;因此添加任务的延迟很低 使用唯一选项对任务进行去重 允许为每个任务设置超时和截止日期 允许将任务…

win10安装了新设备之后电脑没有声音

安装了新设备之后电脑没有声音&#xff0c;查看声音设置&#xff08;我的是win10&#xff09;&#xff0c;选择输出设备&#xff0c;也许是因为新的设备带有输出设备导致。我的显示器&#xff08;华硕 vp228&#xff09;没有音箱&#xff0c;但是估计预留有声音设备接口&#x…

hashcode值相同的字符串

for (int i = 1179395; i <= 1179395; i++) {for (int j = 19968; j <= 40869; j++) {for (int m = 19968; m <= 40869; m++) {if (i == 31 * j + m) {System.out.println((char) j + "" + (char) m);}}}} 一段很扯的代码,生成了一堆hashcode为1179395,…

安装GBase 8t 测试版

安装GBase 8t 测试版 前期计划&#xff1a; 1,安装Win7x64位系统 2,安装VMware-workstation-full-12.5.4 3,安装CentOS-6.4-x86_64-minimal,网络连接使用桥接模式 ip地址规划&#xff1a; 172.17.6.209 gbase gbase 二&#xff0c;操作系统配置 关闭CentOS启动进度条&…

ffmpeg API变更 2009-03-01—— 2017-05-09变更

转载自&#xff1a;http://blog.csdn.net/King1425/article/details/71439943 Add&#xff1a;新增的Change/Rename&#xff1a;修改的Deprecate&#xff1a;过时的。以后很有可能删除。Remove&#xff1a;删除的The last version increases were: libavcodec: 2015-08-28 l…

perf Examples

为什么80%的码农都做不了架构师&#xff1f;>>> These are some examples of using the perf Linux profiler, which has also been called Performance Counters for Linux (PCL), Linux perf events (LPE), or perf_events. Like Vince Weaver, Ill call it perf…

推荐系统中的协同滤波算法___使用SVD

学会观察他人的恐惧&#xff0c;我们会清晰地看到自己。--- 雾满拦江 对于推荐方法&#xff0c;基于内容 和 基于协同过滤 是目前的主流推荐算法&#xff0c;很多电子商务网站的推荐系统都是基于这两种算法的。 协同过滤 是一种基于相似性来进行推荐的算法&#xff0c;主要分为…

Linux ftrace 2.1、ftrace的使用

关于Ftrace的使用&#xff0c;最权威的解读就在”Documentation/trace”文件夹下&#xff0c;我们挑选其中最经典的几个文件来进行翻译&#xff0c;加上自己理解的解读。 参考原文&#xff1a;ftrace - Function Tracer 1、背景&#xff1a; Ftrace本来设计作为一个内部的tr…