AIDL(Android Interface Definition Language ,Android 接口定义语言),定义客户端与服务使用进程间通信 (IPC) 进行相互通信时都认可的编程接口。
只有允许不同应用的客户端用 IPC 方式访问服务,并且想要在服务中处理多线程时,才有必要使用 AIDL。
如果不需要执行跨越不同应用的并发 IPC,就应该通过实现一个 Binder 创建接口;或者,如果想执行 IPC,但根本不需要处理多线程,则使用 Messenger 类来实现接口。
1、创建 AIDL 文件
首先在 java 同级目录 aidl 文件夹,然后创建 .aidl 文件。
// IBookManager.aidl
package com.wshunli.ipc.demo;
// Declare any non-default types here with import statements
import com.wshunli.ipc.demo.Book;
interface IBookManager {
List<Book> getBookList();
void addBook(in Book book);
/**
* Demonstrates some basic types that you can use as parameters
* and return values in AIDL.
*/
void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat,
double aDouble, String aString);
}
在 .aidl
文件中支持的数据类型包括:
- 基本数据类型
- String 和 CharSequence
- List:只支持 ArrayList , 里面的元素都必须被 AIDL 支持
- Map:只支持 HashMap , 里面的元素必须被 AIDL 支持
- 实现 Parcelable 接口的对象
- 所有 AIDL 接口
然后创建实现了 Parcelable 的类:
public class Book implements Parcelable {
public String name;
public Book(String name) {
this.name = name;
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(name);
}
public static Creator<Book> CREATOR = new Creator<Book>() {
@Override
public Book createFromParcel(Parcel source) {
return new Book(source);
}
@Override
public Book[] newArray(int size) {
return new Book[size];
}
};
private Book(Parcel source) {
name = source.readString();
}
@Override
public String toString() {
return "Book{" +
"name='" + name + '\'' +
'}';
}
}
创建 Book.aidl 文件:
// Book.aidl
package com.wshunli.ipc.demo;
// Declare any non-default types here with import statements
parcelable Book;
这时候重新编译程序,工程就会自动生成 BookManager.aidl
接口对应的文件。
app\build\generated\source\aidl\debug\com\wshunli\ipc\demoIBookManager.java
2、创建服务端
服务端使用 IBookManager.Stub() 方法创建 Binder 实例并在 onBind() 方法中返回。
public class BookManagerService extends Service {
private static final String TAG = "BookManagerService";
private CopyOnWriteArrayList<Book> mBookList = new CopyOnWriteArrayList<>();
private Binder mBinder = new IBookManager.Stub(){
@Override
public List<Book> getBookList() throws RemoteException {
return mBookList;
}
@Override
public void addBook(Book book) throws RemoteException {
mBookList.add(book);
}
@Override
public void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, String aString) throws RemoteException {
}
};
public BookManagerService() {
}
@Override
public void onCreate() {
super.onCreate();
mBookList.add(new Book("android"));
mBookList.add(new Book("ios"));
}
@Override
public IBinder onBind(Intent intent) {
return mBinder;
}
}
其中 onCreate() 方法中填充了数据。
当然在 AndroidManife 文件中要配置 Service
<service
android:name="com.wshunli.ipc.demo.BookManagerService"
android:enabled="true"
android:exported="true"
android:process=":remote" />
3、客户端
客户端还是使用 bindService() 方法绑定服务。
public class BookManagerActivity extends AppCompatActivity {
private static final String TAG = "BookManagerActivity";
private ServiceConnection connection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
IBookManager bookManager = IBookManager.Stub.asInterface(service);
try {
List<Book> bookList = bookManager.getBookList();
Log.d(TAG, "onServiceConnected: " + bookList.toString());
} catch (RemoteException e) {
e.printStackTrace();
}
}
@Override
public void onServiceDisconnected(ComponentName name) {
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_book_manager);
Intent intent = new Intent(BookManagerActivity.this, BookManagerService.class);
bindService(intent, connection, BIND_AUTO_CREATE);
}
@Override
protected void onDestroy() {
unbindService(connection);
super.onDestroy();
}
}
其中 IBookManager 对象来调用具体服务器方法,获取数据。
AIDL 的功能远不止这些,后面再深入研究。
参考资料
1、《Android开发艺术探索》 -- 2.4.4 使用 AIDL
2、Android 接口定义语言 (AIDL) | Android Developers
https://developer.android.com/guide/components/aidl
3、Android IPC机制(三)在Android Studio中使用AIDL实现跨进程方法调用 | 刘望舒的博客
http://liuwangshu.cn/application/ipc/3-aidl.html
评论 (0)