簡(jiǎn)介
在android中,常常一個(gè)應(yīng)用需要和另外一個(gè)應(yīng)用進(jìn)程跨進(jìn)程通信,這就不可避免地涉及到了跨進(jìn)程通信。android有種多種方式可以達(dá)到跨進(jìn)程通信的目的,例如文件共享,Bundle,Messenger,Aidl。文件共享存在并發(fā)讀寫(xiě)的問(wèn)題,Bundle傳遞參數(shù)只能局限于基本數(shù)據(jù)類型以及實(shí)現(xiàn)了Parceable或者Serializable接口的對(duì)象 ,本文主要介紹Aidl跨進(jìn)程通信
客戶端實(shí)現(xiàn)
- 定義一個(gè)實(shí)體類實(shí)現(xiàn)Parcelable接口
public class Book implements Parcelable {
public int bookId;
public String bookName;
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(this.bookId);
dest.writeString(this.bookName);
}
public Book() {
}
public Book(int bookId, String bookName) {
this.bookId = bookId;
this.bookName = bookName;
}
protected Book(Parcel in) {
this.bookId = in.readInt();
this.bookName = in.readString();
}
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];
}
};
- 定義一個(gè)Book.aidl類
package com.apache.android.aidl;
parcelable Book;
- 定義接口通信aidle文件
interface IBookManager {
List<Book> getBookList();
void addBook(in Book book);
}
注意這里有一個(gè)坑,就是這里將Book.java和Book.aidl是同在aidl目錄下的(出于方便移植的目的 ),但是android studio在編譯的時(shí)候會(huì)報(bào)錯(cuò),提示找不到Book.java類, 原因是Android Studio 是使用gradle來(lái)構(gòu)建項(xiàng)目的,而Gradle構(gòu)建項(xiàng)目的時(shí)候會(huì)通過(guò)SourceSet來(lái)配置不同的訪問(wèn)路徑,從而加快查找速度-問(wèn)題就出在這里,Gradle 默認(rèn)是將java代碼的訪問(wèn)路徑放在java目錄下的,這樣一來(lái)如果java代碼放在aidl目錄下,gradle自然就找不到這個(gè)java文件了,解決辦法是在gradle中把a(bǔ)idl目錄也配置到sourceSet中去
sourceSets{
main{
java.srcDirs = ['src/main/java', 'src/main/aidl']
}
}
遠(yuǎn)程服務(wù)端實(shí)現(xiàn)
定義一個(gè)BookManagerService服務(wù),在manifest清單文件中配置為 remote進(jìn)程
public class BookManagerService extends Service {
private CopyOnWriteArrayList<Book> mBookList = new CopyOnWriteArrayList<>();
@Override
public void onCreate() {
super.onCreate();
mBookList.add(new Book(1,"android"));
mBookList.add(new Book(2,"ios"));
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return binder;
}
private IBinder binder = new IBookManager.Stub() {
@Override
public List<Book> getBookList() throws RemoteException {
return mBookList;
}
@Override
public void addBook(Book book) throws RemoteException {
mBookList.add(book);
}
};
}
創(chuàng)建一個(gè)IBinder對(duì)象并在onBinder方法中返回,這個(gè)對(duì)象繼承自IBookManager.Stub,并實(shí)現(xiàn)它內(nèi)部的Aidl方法
客戶端使用
客戶端使用就比較簡(jiǎn)單了, 綁定遠(yuǎn)程服務(wù),綁定成功后將服務(wù)端返回的Binder對(duì)象轉(zhuǎn)換成Aidlj可口,然后就可以通過(guò)這個(gè)接口去調(diào)用服務(wù)器端的方法了
Intent intent = new Intent(this,BookManagerService.class);
bindService(intent,connection, Context.BIND_AUTO_CREATE);
private ServiceConnection connection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
NLog.d(TAG, "onServiceConnected");
manager = IBookManager.Stub.asInterface(service);
}
@Override
public void onServiceDisconnected(ComponentName name) {
NLog.d(TAG, "onServiceDisconnected");
manager = null;
}
};
@Override
protected void onDestroy() {
super.onDestroy();
unbindService(connection);
}
private void addBook(){
try {
if (manager == null){
return;
}
Book book = new Book(mCount.getAndAdd(1), "Android進(jìn)階: "+mCount.get());
manager.addBook(book);
printBookList();
} catch (RemoteException e) {
e.printStackTrace();
}
}