Android之使用AIDL进行IPC(一)
来源:互联网 发布:三国吴国知乎 编辑:程序博客网 时间:2024/06/04 22:47
写在前面
在前面有一篇是用Messenger来进行IPC(Android之使用Messenger进行IPC),Messenger是对AIDL的一个封装,也就是其下面还是AIDL,本篇就是直接用AIDL来实现。
我觉得还是要分开多篇来记录,这一篇主要是记录怎么实现,之后再记录一些原理性的东西。
这里是在一道题目的背景下来实现的,所以有些东西我们可以忽略,在这篇博客里我们应该是重点在AIDL上。完整的代码在这里:GitHub。
结构和流程
我们只要关注一个整体的结构先:本Project有三个module,分别是app,licensekeylibrary和serverapp。那么app和serverapp就是两个不同的进程,我们要实现的是这两者的交互,
licensekeylibrary是一个依赖库,他们两者都有依赖,主要是在这个题目下用来做一些分装和工具类的提供而已。
服务端
先看下服务端的项目结构:
当我们右键新建AIDL文件的时候,AS就会自动帮我们建立aidl文件夹(就蓝色的那个),所以之后我们的aidl文件都写在这个文件夹下即可,而且因为客户端也是要跟服务端一样有同样的aidl文件,所以拷贝也方便。
接口准备
首先新建ILicense.aidl文件:
// ILicense.aidlpackage com.jdnew.serverapp.aidl;// Declare any non-default types here with import statementsimport com.jdnew.serverapp.aidl.RootLicenseData;interface ILicense { RootLicenseData returnLicense(String licenseData); String returnCheckResult(String submitData);}
这里主要是建立与客户端通信的接口,returnLicense方法主要是接收客户端提交的licenseData,然后经过一系列处理后返回RootLicenseData 对象给客户端;returnCheckResult方法也类似,主要是接收客户端提交的submitData,然后返回String校验结果给客户端。
因为我们这里用到了一个自定义类RootLicenseData,所以有几个地方要注意,首先这个类必须实现Parcelable:
public class RootLicenseData implements Parcelable { private String license; private byte[] rsaPublicKey; public String getLicense() { return license; } public void setLicense(String license) { this.license = license; } public byte[] getRsaPublicKey() { return rsaPublicKey; } public void setRsaPublicKey(byte[] rsaPublicKey) { this.rsaPublicKey = rsaPublicKey; } public RootLicenseData (String license , byte[] rsaPublicKey){ this.license = license; this.rsaPublicKey = rsaPublicKey; } protected RootLicenseData(Parcel in) { license = in.readString(); rsaPublicKey = in.createByteArray(); } public static final Creator<RootLicenseData> CREATOR = new Creator<RootLicenseData>() { @Override public RootLicenseData createFromParcel(Parcel in) { return new RootLicenseData(in); } @Override public RootLicenseData[] newArray(int size) { return new RootLicenseData[size]; } }; @Override public int describeContents() { return 0; } @Override public void writeToParcel(Parcel parcel, int i) { parcel.writeString(license); parcel.writeByteArray(rsaPublicKey); }}
另外它需要一个同名的aidl文件,RootLicenseData.aidl
// RootLicenseData.aidlpackage com.jdnew.serverapp.aidl;// Declare any non-default types here with import statementsparcelable RootLicenseData;
创建完后记得rebuild一下,让IDE自动生成一些东西。
服务端实现
一些基础的弄好后,就要开始服务端的实现,部分代码如下:
public class LicenseService extends Service { private final String TAG = "LicenseService"; private Binder linsenseBinder = new ILicense.Stub() { @Override public com.jdnew.serverapp.aidl.RootLicenseData returnLicense(String licenseData) throws RemoteException { //对传入的licenseData做处理然后写入到rootLicenseData里返回 RootLicenseData rootLicenseData = new RootLicenseData(licenseKey, rsaPublicKey); return rootLicenseData; } @Override public String returnCheckResult(String submitData) throws RemoteException { //对传入的submitData做处理,并返回String结果 return "result"; }; @Nullable @Override public IBinder onBind(Intent intent) { return linsenseBinder; }}
注册服务
接着在serverapp的Manifest文件里注册该服务:
<service android:name="com.jdnew.serverapp.service.LicenseService" android:exported="true"> <intent-filter> <category android:name="android.intent.category.DEFAULT"/> <action android:name="com.jdnew.serverapp.service.LicenseService"/> </intent-filter> </service>
好了,接下来看app客户端:
客户端
前面说过,客户端需要与服务端同样的aidl,所以我们把服务端的拷贝过来:
然后是调用Service的代码:
private ILicense mILicense; private ServiceConnection mServiceConnection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { mILicense = ILicense.Stub.asInterface(service); } @Override public void onServiceDisconnected(ComponentName name) { } };
然后就是对ILicense的使用(部分代码如下):
public void genLicenseKey(String name) { RootLicenseData rootLicenseData = mILicense.returnLicense(genLicenseKeyUtil.getDataToGenLicense(name)) ; } public void submitData(String licenseKey) { try { String result = mILicense.returnCheckResult(submitData); if (result.equals("true")) { mIRegistView1.checkLicenseKeySuccess("验证成功"); }else { mIRegistView1.checkLicenseKeyFailed("验证失败"); } } catch (RemoteException e) { e.printStackTrace(); } }
然后绑定服务即可:
Intent intent = new Intent(); intent.setAction("com.jdnew.serverapp.service.LicenseService"); intent.setPackage("com.jdnew.serverapp"); mContext.bindService(intent , mServiceConnection , Context.BIND_AUTO_CREATE);
记得这里Intent要setPackage,不然在5.0以上会报错。
这样我们就完成了一个简单的AIDL。
- Android之使用AIDL进行IPC(一)
- Android IPC 之 AIDL(一)
- Android IPC机制之AIDL的使用
- Android IPC之AIDL使用解析
- Android IPC之AIDL的使用
- 安卓IPC之aidl使用(一)--aidl常见使用
- Android IPC之AIDL
- Android IPC 之AIDL
- Android IPC之AIDL
- Android IPC 之 AIDL
- Android IPC之AIDL
- Android IPC 之 AIDL (二)
- 跨进程间如何进行AIDL IPC 通信(一)
- 【Android开发艺术探索】IPC机制(四)-使用AIDL进行跨进程通信
- Android IPC之AIDL浅谈
- android IPC机制之 AIDL
- Android的IPC机制(一)——AIDL的使用
- Android的IPC机制(一)——AIDL的使用
- 实现一个函数,将一个字符串中的空格替换成“ ”。例如,当字符串为We Are Happy.则经过替换之后的字符串为We Are Happy
- Shopping Offers问题及解法
- 连接数据库语句
- Python基础小笔记《2017-09-24》
- decaf 接口用法
- Android之使用AIDL进行IPC(一)
- [笔记]关于tarjan求连通分量 & 缩点
- iOS Compiling IB documents for earlier than iOS 7 is no longer supported
- 我的seajs实例
- python tornado 模板扩展
- SQL,计算group by分组后组内不同值的数量
- nginx配置多站点访问
- Eclipse+Tomcat+MAVEN+SVN项目完整环境搭建
- Mybatis Generator(简称MBG)的最完整配置文件详解