Android AIDL介绍
一、作用
AIDL(Android Interface Definition Language, Android接口定义语言)用于跨进程通信。
二、用法——服务端
(1)Android Studio中创建aidl
在生成的aidl文件中自定义所需接口,如下我定义了getText()和setText()两个接口:
注意:AIDL中支持的数据类型为int,short,long,char,double,byte,float,boolean,如果需要使用自定义的对象,则需要自定义的对象实现Parcelable接口。
rebuild一下,如果在app/build/generated下看到如下结果,证明你的aidl已经创建成功:
(2)创建服务——实现接口
public class MyService extends Service {
private String mText = "";
IMyAidlTestInterface.Stub mBinder = new IMyAidlTestInterface.Stub() {
@Override
public void setText(String text) throws RemoteException {
mText = text;
}
@Override
public String getText() throws RemoteException {
return mText;
}
};
public MyService() {
}
@Override
public IBinder onBind(Intent intent) {
return mBinder;
}
}
AndroidManifest.xml:
<service
android:name=".MyService"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="com.test.server"/>
</intent-filter>
</service>
三、用法——客户端
常见的应用场景是客户端与服务端并不在同一个工程中,因此我们举例使用的是两个工程,分为客户端和服务端。客户端如果想使用服务端定义的接口,需要在客户端中也创建aidl。且接口与包名与服务端一致。可直接将服务端的aidl文件夹直接复制至客户端中。
以下的demo为点击发送按钮后,获取Editext中的字符串并传给服务端,客户端再从服务端获取该字符串。
layout:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<EditText
android:id="@+id/et_input"
android:layout_marginTop="116dp"
android:layout_width="100dp"
android:layout_height="wrap_content"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent">
</EditText>
<TextView
android:id="@+id/tv_output"
android:layout_marginTop="16dp"
android:layout_width="100dp"
android:layout_height="wrap_content"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
android:textSize="16sp"
app:layout_constraintTop_toBottomOf="@+id/et_input">
</TextView>
<Button
android:id="@+id/btn_send"
android:layout_marginTop="116dp"
android:layout_width="100dp"
android:layout_height="wrap_content"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tv_output"
android:text="发送">
</Button>
</androidx.constraintlayout.widget.ConstraintLayout>
MainActivity:
public class MainActivity extends AppCompatActivity {
private EditText mEtInput;
private TextView mTvOutput;
private Button mBtnSend;
private IMyAidlTestInterface mIMyAidlInterface;
private ServiceConnection mConn = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
mIMyAidlInterface = IMyAidlTestInterface.Stub.asInterface(iBinder);
}
@Override
public void onServiceDisconnected(ComponentName componentName) {
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
setListener();
startService();
}
private void initView(){
mEtInput = findViewById(R.id.et_input);
mTvOutput = findViewById(R.id.tv_output);
mBtnSend = findViewById(R.id.btn_send);
}
private void setListener(){
mBtnSend.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
try {
mIMyAidlInterface.setText(mEtInput.getText().toString());
mTvOutput.setText(mIMyAidlInterface.getText());
} catch (RemoteException e) {
e.printStackTrace();
}
}
});
}
private void startService(){
Intent intent = new Intent("com.test.server");
intent.setPackage("com.test.aidltest");
bindService(intent,mConn,BIND_AUTO_CREATE);
}
@Override
protected void onDestroy() {
super.onDestroy();
unbindService(mConn);
}
}
效果如下: