系列文章
AIDL的基本使用
AIDL之自定义数据类型
AIDL之修饰符in,out,inout
AIDL之重连方法
AIDL之接口注册/解注册
AIDL之连接池
知识点
- AIDL的基本概念
- AIDL的基本使用案例
一、AIDL的基本概念
AIDL定义
:个人理解就是Android开发中提供的一种快速实现binder的工具,而binder就是一种跨进程通信,也可以不用AIDL,自己实现binder来达到同样的效果
AIDL支持的基本类型
: String,int,long,boolean,float,double,ArrayList,HashMap,Parcelable
二、AIDL的基本使用案例
本篇文章只实现最简单的两个进程通信,步骤如下:
- 先定义一个IPersion.aidl接口
interface IPerson {
void setName(String s);
String getName();
}
- 同步一下代码让IDE自动生成代码,生成后的代码路径为
build/generated/source/aidl/debug/包名/IPerson
- 编译服务端AIDLService,实例化binder对象并返回给客户端
public class AIDLService extends Service {
private String name;
private Binder binder=new IPerson.Stub() {
@Override
public void setName(String s) throws RemoteException {
name=s;
}
@Override
public String getName() throws RemoteException {
return name;
}
};
@Nullable
@Override
public IBinder onBind(Intent intent) {
LogUtil.d("onBind");
return binder;
}
}
- 客户端通过binderService获取binder后,就可以提供调用相应的方法
public class AIDLClientAcitvity extends Activity {
@BindView(R.id.btn_bindservice)
Button btnBindservice;
@BindView(R.id.btn_setname)
Button btnSetname;
@BindView(R.id.btn_getName)
Button btnGetName;
@BindView(R.id.et_name)
EditText etName;
private IPerson iPerson;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_aidl_client);
ButterKnife.bind(this);
}
@OnClick({R.id.btn_bindservice, R.id.btn_setname, R.id.btn_getName})
public void onViewClicked(View view) {
switch (view.getId()) {
case R.id.btn_bindservice:
bindServiceByAidl();
break;
case R.id.btn_setname:
setName();
break;
case R.id.btn_getName:
getName();
break;
}
}
private void bindServiceByAidl() {
Intent intent = new Intent(this, AIDLService.class);
bindService(intent, new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
LogUtil.d("onServiceConnected");
iPerson = IPerson.Stub.asInterface(service);
}
@Override
public void onServiceDisconnected(ComponentName name) {
LogUtil.d("onServiceDisconnected");
}
}, BIND_AUTO_CREATE);
}
private void setName() {
if (iPerson != null) {
try {
iPerson.setName(etName.getText().toString().trim());
} catch (RemoteException e) {
e.printStackTrace();
Toast.makeText(this, "setName error="+e, Toast.LENGTH_SHORT).show();
}
}
}
private void getName(){
if(iPerson!=null){
try {
Toast.makeText(this, iPerson.getName(), Toast.LENGTH_SHORT).show();iPerson.getName();
} catch (RemoteException e) {
e.printStackTrace();
Toast.makeText(this, "getName error="+e, Toast.LENGTH_SHORT).show();
}
}
}
}
(ps:可能有人会觉得这只是Activity与Service的通信,但是这个Service是可以换成其他应用的Service,当一个应用于另一个应用的服务通信的时候,就是跨进程通信的一种表现了,不过需要注意的是,服务端和客户端的AIDL包名路径要一致)
总结
本篇提供了一个最简单的aidl的使用方式,其实就是我们常用的bindService方式,但是从另一个概念上去理解这样的过程,会发现bindService所做事情的意义是很不一样的。
大家也可以去看下AIDL生成后的代码,尝试去理解下Stub.asInterface
和Stub()
的作用,你会发现不一样的东西
(ps:系列文章后续会更新完整)