系列文章
AIDL的基本使用
AIDL之自定義數據類型
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:系列文章後續會更新完整)
Demo地址
https://github.com/returntolife455/DemoList
鏈接:https://www.jianshu.com/p/5043a1a69269