一、AIDL是什么
AIDL是Android中进程间通信IPC(Inter-Process Communication)方式中的一种,AIDL是Android Interface definition language的缩写,对于小白来说,AIDL的作用是让你可以在自己的APP里绑定一个其他APP的service,这样你的APP可以和其他APP交互。
二、AIDL使用
2.1 AIDL server端代码编写
目录结构如下图所示:
其中:
- IMyAidlInterface.aidl表示我们定义的aidl接口
- User.aidl表示我们传输的自定义类型
- MainActivity表示主页面
- MyService表示自定义服务,用来返回IMyAidlInterface.Stub的实例
- User表示具体我们传输的自定义类型,与User.aidl的区别是,User.aidl只是定义了引用
IMyAidlInterface.aidl
// IMyAidlInterface.aidl
package com.example.aidlserver;
import com.example.aidlserver.User;
// 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.
*/
String getName();
User getUserName(String data);
}
User.aidl
// User.aidl
package com.example.aidlserver;
parcelable User;
MyService
package com.example.aidlserver;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
import androidx.annotation.Nullable;
public class MyService extends Service {
private static final String TAG = "MyService";
private static User user;
// public MyService() {
// }
@Override
public void onCreate() {
super.onCreate();
user = new User("zhangsan");
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
Log.d(TAG, "onBind" +
"" );
return new MyBinder();
}
static class MyBinder extends IMyAidlInterface.Stub {
@Override
public String getName() throws RemoteException {
return "test";
}
@Override
public User getUserName(String data) throws RemoteException {
return user;
}
}
}
User
package com.example.aidlserver;
import android.os.Parcel;
import android.os.Parcelable;
public class User implements Parcelable {
public User(String name) {
this.name = name;
}
public User(Parcel in) {
name = in.readString();
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
'}';
}
String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public static final Creator<User> CREATOR = new Creator<User>() {
@Override
public User createFromParcel(Parcel in) {
return new User(in);
}
@Override
public User[] newArray(int size) {
return new User[size];
}
};
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(name);
}
}
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.aidlserver">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service android:name=".MyService"
android:exported="true"
android:enabled="true">
</service>
</application>
</manifest>
2.2 AIDL client端代码编写
client端的目录代码结构如下图所示:
其中IMyAidlInterface.aidl与User.aidl必须保证与server端完全一致,所以将server端的aidl文件夹复制到client端就可以了
User也需要与Server端保持一致,包名也需要一致,所以在com.example下新建一个aidlserver包,在该包下复制server端的User代码
MainActivity代码
package com.example.aidlclient;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
import android.view.View;
import androidx.appcompat.app.AppCompatActivity;
import com.example.aidlserver.IMyAidlInterface;
public class MainActivity extends AppCompatActivity {
private IMyAidlInterface iMyAidlInterface;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
bindService();
}
ServiceConnection serviceConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
iMyAidlInterface = IMyAidlInterface.Stub.asInterface(service);
}
@Override
public void onServiceDisconnected(ComponentName name) {
serviceConnection = null;
}
};
private void bindService() {
Intent intent = new Intent();
intent.setClassName("com.example.aidlserver", "com.example.aidlserver.MyService");
bindService(intent, serviceConnection, BIND_AUTO_CREATE);
}
private static final String TAG = "MainActivity";
public void onClick(View view) {
try {
Log.d(TAG, "onClick" +
", iMyAidlInterface = " + iMyAidlInterface.getName() +
", iMyAidlInterface.getUserName(1) = " + iMyAidlInterface.getUserName("1") +
"" +
"");
} catch (RemoteException e) {
e.printStackTrace();
}
}
}
可以在控制台查看打印日志
参考资料
Android中AIDL的使用详解