AIDL学习总结:使用AIDL实现跨进程通信
前言
本文是对AIDL跨进程通信的学习和总结,主要介绍了AIDL的基本概念和使用方法,通过一个简单的Demo来展示AIDL跨进程通信,是对自己前几天学习的简要总结。
AIDL
基本概念
AIDL(Android Interface Definition Language)是一种接口定义语言,用于生成可以在Android设备上两个进程之间进行进程通信,AIDL内部主要通过Binder机制来实现, 适用于进程之间交互频繁、通信数据量小的场景。
在使用AIDL进行跨进程通信的时候,通常将请求通信的一方称之为客户端(Client),客户端的主要工作就是发送数据;而接收通信数据的一方称之为服务端(Server),服务端主要工作是处理客户端发送过来的数据,并通过回调(Callback)的方式返回客户端数据,实现双向通信。
AIDl数据类型
AIDL支持以下数据类型:
Java的8种基本类型,即int、long、char等。
String和CharSequence。
List:其中的每个元素都必须是AIDL支持的。客户端实际接收的具体类始终是ArrayList,但生成的方法使用的是List接口。
Map:其中的每个元素都必须是AIDL支持的。客户端实际接收的具体类始终是HashMap,但生成的方法使用的是Map接口。
Parcelable:必须要显式import,即使它跟.aidl是同一个包下。
AIDL接口:必须要显式import,即使它跟.aidl是同一个包下。
AIDL中的方法:可有零、一或多个参数,可有返回值或void。
AIDL中除了基本数据类型(默认为in,不能是其他方向),其他类型的参数必须标上方向:
in
,表示输入型参数,由客户端赋值;
out
,表示输出型参数,由服务端赋值;
inout
,表示输入输出型参数,可由客户端或服务端赋值;
AIDL只expose方法,不会expose静态变量。
第一个Demo:Client向Server发送数据
第一个Demo是Client输入用户名和密码,并通过AIDL接口发送给Server,简单展示了AIDL的基本用法。
Server端工程
新建工程AIDLServer,作为服务端App,在main文件夹下建立一个aidl文件夹,用于存放aidl文件,新建aidl文件IMyAidlInterface.aidl:
文件内容如下:
// IMyAidlInterface.aidl
package com.jason.aidlserver;
import com.jason.aidlserver.ICallback;
// Declare any non-default types here with import statements
interface IMyAidlInterface {
/**
* Demonstrates some basic types that you can use as parameters
* and return values in AIDL.
*/
void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat,
double aDouble, String aString);
void login(String userName,String passWord);
}
其中,方法basicTypes
是自动生成的,如果不需要的话,完全可以删掉。方法login
是我们自定义的,用于发送用户名和密码。生成之后,点击Make Project按钮,生成AIDL对应的.java
文件:
如果点开这个文件的话,会看到AS对.aidl
文件中的interface的具体实现,我们在这里不再对源码进行解读,你只需要知道,里面的Stub
抽象类是实现AIDL接口核心部分,它继承自Binder(这也直接印证了AIDL接口依赖于Binder实现) 。
然后在我们的Java源文件包中新建一个Service,这里命名为AIDLService,用于实现接收Client的数据:
package com.jason.aidlserver;
public class AIDLService extends Service {
@Override
public IBinder onBind(Intent intent) {
return new MyBinder();
}
public interface OnLoginListener {
void login(String userName, String passWord);
}
private OnLoginListener onLoginListener;
public void setOnLoginListener(OnLoginListener onLoginListener) {
this.onLoginListener = onLoginListener;
}
class MyBinder extends IMyAidlInterface.Stub {
@Override
public void basicTypes(int anInt, long aLong, boolean aBoolean,
float aFloat, double aDouble, String aString) throws RemoteException {
}
@Override
public void login(String userName, String passWord) throws RemoteException {
if (onLoginListener != null)