简介
AIDL 意思即 Android Interface Definition Language,翻译过来就是Android接口定义语言,是用于跨进程之间通信
AIDL支持的数据类型分为如下几种:
- 八种基本数据类型:byte、char、short、int、long、float、double、boolean
- String,CharSequence
- 实现了Parcelable接口,Serializable接口的数据类型
- List 类型。List承载的数据必须是AIDL支持的类型,或者是其它声明的AIDL对象
- Map类型。Map承载的数据必须是AIDL支持的类型,或者是其它声明的AIDL对象
项目简介
- aidl_server提供两个数字的假发
- aidl_client调用aidl_server提供的方法,计算两个数字的和
AIDL创建方式
注意:
- 服务器端的AIDL文件包需要和客户端的包名一致
- 在aidl文件中,如果需要应用其他的aidl文件,需要手动import(好似我的android studio不会自动导入)
项目创建
- 服务端
服务端目录
Number.aidl
package com.zkq.aidl_server;
// Declare any non-default types here with import statements
parcelable Number;
Number.aidl文件中的parcelable是指引到同包名下的Number文件
Number需要继承Parcelable 实现序列化
public class Number implements Parcelable {
int num;
public Number(int num) {
this.num = num;
}
public int getNum() {
return num;
}
public void setNum(int num) {
this.num = num;
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(this.num);
}
public Number() {
}
protected Number(Parcel in) {
this.num = in.readInt();
}
public static final Creator<Number> CREATOR = new Creator<Number>() {
@Override
public Number createFromParcel(Parcel source) {
return new Number(source);
}
@Override
public Number[] newArray(int size) {
return new Number[size];
}
};
}
NumberManager.aidl实现了三个接口
- add 两个数字相加
- registerOnCountListener 注册相加后的结果监听器
- unregisterOnCountListener取消注册结果监听器
这里需要注意import了两个其他aidl文件(我的android studio不会自动引包,也不报错,但是编译时候会出错 Process 'command 'D:\android_sdk\build-tools\28.0.3\aidl.exe'' finished with non-zero exit value 1),所以需要手动添加
import com.zkq.aidl_server.Number;
import com.zkq.aidl_server.OnCountListener;
interface NumberManager {
void add( in Number num1,in Number num2);
void registerOnCountListener(in OnCountListener listener);
void unregisterOnCountListener(in OnCountListener listener);
}
OnCountListener.aidl 实现了计算结果接口
import com.zkq.aidl_server.Number;
interface OnCountListener {
void result(in Number result);
}
MyService文件
public class MyService extends Service {
private RemoteCallbackList<OnCountListener> remoteCallbackList;
NumberManager.Stub stub = new NumberManager.Stub() {
@Override
public void add(Number num1, Number num2) {
int n1 = num1.getNum();
int n2 = num2.getNum();
Number result = new Number(n1+n2);
int count = remoteCallbackList.beginBroadcast();
for (int i = 0; i < count; i++) {
OnCountListener broadcastItem = remoteCallbackList.getBroadcastItem(i);
if (null!=broadcastItem){
try {
broadcastItem.result(result);
} catch (RemoteException e) {
e.printStackTrace();
}
}
}
remoteCallbackList.finishBroadcast();
}
@Override
public void registerOnCountListener(OnCountListener listener) {
remoteCallbackList.register(listener);
}
@Override
public void unregisterOnCountListener(OnCountListener listener) {
remoteCallbackList.unregister(listener);
}
};
public MyService() {
remoteCallbackList = new RemoteCallbackList<>();
}
@Override
public IBinder onBind(Intent intent) {
return stub.asBinder();
}
}
需要在AndroidManifest.xml中注册
<service
android:name=".MyService"
android:enabled="true"
android:exported="true"></service>
服务端就完成了
- 客户端
注意
- NumberManager.aidl ,Number.aidl ,OnCountListener.aidl的包名需要和服务端一直,可以直接拷贝过来
- Number.class文件包名也需要和服务器一直,可以直接拷贝过来
我们这里只要就是在mainActivity里面,提取了几个重要的方法
绑定MyService
private void bindServer() {
Intent intent = new Intent();
intent.setClassName("com.zkq.aidl_server", "com.zkq.aidl_server.MyService");
bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE);
}
获得NumberManager
private ServiceConnection serviceConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
NumberManager manager = NumberManager.Stub.asInterface(service);
}
@Override
public void onServiceDisconnected(ComponentName name) {
manager = null;
}
};
相加的结果监听器
private OnCountListener.Stub myOnCountListener = new OnCountListener.Stub() {
@Override
public void result(final Number result) throws RemoteException {
Log.d("zkq", "-----> " + result.getNum());
}
};
注册监听器
manager.registerOnCountListener(myOnCountListener);
取消注册监听器
manager.unregisterOnCountListener(myOnCountListener);
两个方法相加
manager.add(number1, number2);
完整代码如下
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private Button mRegisterBtn;
private Button mUnregisterBtn;
private EditText mNum1Et;
private EditText mNum2Et;
private Button mAddBtn;
private EditText mResultEt;
NumberManager manager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
bindServer();
}
private ServiceConnection serviceConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
manager = NumberManager.Stub.asInterface(service);
}
@Override
public void onServiceDisconnected(ComponentName name) {
manager = null;
}
};
private OnCountListener.Stub myOnCountListener = new OnCountListener.Stub() {
@Override
public void result(final Number result) throws RemoteException {
Log.d("zkq", "-----> " + result.getNum());
mResultEt.post(new Runnable() {
@Override
public void run() {
mResultEt.setText(""+result.getNum());
}
});
}
};
private void bindServer() {
Intent intent = new Intent();
intent.setClassName("com.zkq.aidl_server", "com.zkq.aidl_server.MyService");
bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE);
}
private void initView() {
mRegisterBtn = (Button) findViewById(R.id.btn_register);
mRegisterBtn.setOnClickListener(this);
mUnregisterBtn = (Button) findViewById(R.id.btn_unregister);
mUnregisterBtn.setOnClickListener(this);
mNum1Et = (EditText) findViewById(R.id.et_num1);
mNum2Et = (EditText) findViewById(R.id.et_num2);
mAddBtn = (Button) findViewById(R.id.btn_add);
mAddBtn.setOnClickListener(this);
mResultEt = (EditText) findViewById(R.id.et_result);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btn_register:
// TODO 19/08/07
try {
manager.registerOnCountListener(myOnCountListener);
} catch (RemoteException e) {
e.printStackTrace();
}
break;
case R.id.btn_unregister:
// TODO 19/08/07
try {
manager.unregisterOnCountListener(myOnCountListener);
} catch (RemoteException e) {
e.printStackTrace();
}
break;
case R.id.btn_add:
// TODO 19/08/07
if (TextUtils.isEmpty(mNum1Et.getText()) || TextUtils.isEmpty(mNum2Et.getText())) {
return;
}
int param1 = Integer.valueOf(mNum1Et.getText().toString());
int param2 = Integer.valueOf(mNum2Et.getText().toString());
Number number1 = new Number(param1);
Number number2 = new Number(param2);
try {
manager.add(number1, number2);
} catch (RemoteException e) {
e.printStackTrace();
}
break;
default:
break;
}
}
}
demo下载 demo下载