前言
关于AIDL的原理以及详细介绍,我在Binder机制原理一文中有讲到,这里就不再赘述。本篇文章以实战为核心,写一个AIDL操作实例出来
AIDL与Messenger的区别就是AIDL支持并发处理请求,也就是多进程,多线程的情况。而Messenger是多进程,单线程
demo的github地址:https://github.com/LJHnb666666/AIDLDemo
1.实现思路
还是需要客户端,服务端Service。除此之外,还需要一个实体类做客户端和服务端交互的Bean,还需要AIDL文件定义操作的接口。
demo结构如图

2.具体步骤
①写实体类Book
这里需要注意,Book必须实现Parcelable接口,标明其是可序列化的。
/**
* Created by didiwei on 2022/5/10
* desc: Book实体类
*/
public class Book implements Parcelable {
String name;//书名
int cost;//价钱
public Book(String name, int cost) {
this.name = name;
this.cost = cost;
}
@Override
public String toString() {
return "Book{" +
"name='" + name + '\'' +
", cost=" + cost +
'}';
}
//注意:以下均为Parcelable接口需要实现的方法
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(name);
dest.writeInt(cost);
}
//这个方法我用编译器始终搞不出来,建议大家直接复制粘贴这里
public static final Parcelable.Creator<Book> CREATOR = new Parcelable.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 in){
this.name = in.readString();
this.cost = in.readInt();
}
}
②写AIDL,定义接口
注意:
(1)如果要在AIDL接口文件中使用自定义的Parcelable对象或者AIDL对象,必须显式的 import 进来,即使它们在同一个包内。
(2)如果在AIDL接口文件用到了Parcelable对象,必须新建一个和它同名的AIDL文件,并在其中声明它为parcelable类型
所以我这边要创建两个AIDL文件,一个是定义接口,一个是与Book同名的AIDL文件
IBookManager.aidl
// IBookManager.aidl
import com.example.aidldemo.Book;
interface IBookManager {
void addBook(in Book book);
List<Book> getBookList();
}
Book.aidl
// Book.aidl
parcelable Book;
③服务端Service
记得在menifest里面给Service新启进程
主要就是创建IBookManager.Stub对象,并重写接口里面的方法。同时通过onBind方法把IBookManager.Stub对象返回
public class MyService extends Service {
private CopyOnWriteArrayList<Book> bookList;//CopyOnWriteArrayList支持并发读写
public MyService(){
bookList = new CopyOnWriteArrayList<>();
}
private IBookManager.Stub stub = new IBookManager.Stub() {
@Override
public void addBook(Book book) throws RemoteException {
Log.v("ljh","这里是Service,新增的书为" + book);
bookList.add(book);
}
@Override
public List<Book> getBookList() throws RemoteException {
return bookList;
}
};
@Override
public IBinder onBind(Intent intent) {
return stub;
}
}
④客户端
主要就是根据ServiceConnection返回的Binder对象,调用IBookManager.Stub.asInterface()方法,给IBookManager接口赋值,从而进行进程间通信
/**
* Created by didiwei on 2022/5/10
* desc: AIDL的一个小实例,MainActivity扮演客户端的角色
*/
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
Button connect;
Button addBook;
Button getBooks;
IBookManager iBookManager;
ServiceConnection serviceConnection;
Boolean isBind;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
isBind = false;
connect = findViewById(R.id.btn_bindService);
addBook = findViewById(R.id.btn_addBook);
getBooks = findViewById(R.id.btn_getBooks);
connect.setOnClickListener(this::onClick);
addBook.setOnClickListener(this::onClick);
getBooks.setOnClickListener(this::onClick);
serviceConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
Log.v("ljh","这里是客户端,与Service连接成功");
iBookManager = IBookManager.Stub.asInterface(service);
isBind = true;
}
@Override
public void onServiceDisconnected(ComponentName name) {
Log.v("ljh","这里是客户端,与Service断开连接");
}
};
}
@Override
public void onClick(View v) {
switch (v.getId()){
case R.id.btn_bindService:
bindService(new Intent(MainActivity.this,MyService.class),serviceConnection, Context.BIND_AUTO_CREATE);
break;
case R.id.btn_addBook:
try {
iBookManager.addBook(new Book("新书",10));
} catch (RemoteException e) {
e.printStackTrace();
}
break;
case R.id.btn_getBooks:
try {
List<Book> bookList = iBookManager.getBookList();
Log.v("ljh","这里是客户端,从Service获取的书的集合为:"+ bookList);
} catch (RemoteException e) {
e.printStackTrace();
}
break;
default:
break;
}
}
@Override
protected void onStop() {
super.onStop();
if(isBind){
unbindService(serviceConnection);
isBind = false;
}
}
}
3.项目地址和文章推荐
项目地址:https://github.com/LJHnb666666/AIDLDemo
好文推荐:https://juejin.cn/post/7024376277436121118#heading-1
本文是一篇关于AIDL(Android Interface Definition Language)的实战教程,重点在于如何使用AIDL进行进程间通信(IPC)。内容包括:AIDL与Messenger的区别,实现思路,详细步骤(创建实体类Book、定义AIDL接口、服务端Service实现和客户端操作),并提供了项目源码链接。
771

被折叠的 条评论
为什么被折叠?



