本技術博文計劃分為三個系列:
一、AIDL的基礎。
二、AIDL之Messenger,http://blog.csdn.net/wangqiubo2010/article/details/78615047
三、AIDL終極篇之AIDL架構設計,http://blog.csdn.net/wangqiubo2010/article/details/78625846。
一,AIDL的本質可以從以下來了解。
1、AIDL專門為android中的跨程序通訊設計。通過以下對其他跨程序通訊的幾種方式的弱點來解析AIDL的優點。ContentProvider、Broadcast 這兩種底層也是通過IBinder來實作,其使用範圍為系統級的(重量級的),主要用于應用程式和JNI(本地方法庫)之間通訊,例如系統通知、電話本、藍牙等;sharepreference多線程對其讀寫會出現安全性問題,并且sharepreference有緩存資料;Socket通訊,主要用于網絡;serializable序列化是重量級的,并且AIDL中跨程序傳送也是序列化,隻是這個序列化是輕量級的Parcelable。
2、AIDL的跨程序通訊本質為 IBinder。
3、AIDL檔案最好是放在同一個包中,因為Client 和 service必須同時且完全擁有同一份AIDL檔案,否則無法進行通訊。
4、傳送對象必須實作Parcelable,并且這個對象需要定義一份AIDL檔案,檔案格式如下:
傳送的對象類為Book.java,其需要另外定義一個Book.aidl檔案,結構如下
package com.example.wangqiubo.myaidl;
parcelable Book;
5、服務端實作AIDL的本質是實作Stub ,例如IBooksAidlInterface.Stub 。
二、具體應用。
1、android studio定義一個AIDL檔案,如下。
// IBooksAidlInterface.aidl
package com.example.wangqiubo.myaidl;
import com.example.wangqiubo.myaidl.Book;
import com.example.wangqiubo.myaidl.IBookCallBackInterface;
interface IBooksAidlInterface {
List<Book> getBookList();
void addBook(in Book book);
void registerBookEvent(IBookCallBackInterface bookEvent);
void unregisterBookEvent(IBookCallBackInterface bookEvent);
}
2、實作本AIDL借口,即是實作 IBooksAidlInterface.Stub。
//BookImpl.java
package com.example.myservice;
import android.os.RemoteException;
import com.example.wangqiubo.myaidl.Book;
import com.example.wangqiubo.myaidl.IBookCallBackInterface;
import com.example.wangqiubo.myaidl.IBooksAidlInterface;
import java.util.ArrayList;
import java.util.List;
public class BookImpl extends IBooksAidlInterface.Stub {
List<Book> books = new ArrayList<>();
@Override
public List<Book> getBookList() throws RemoteException {
return books;
}
@Override
public void addBook(Book book) throws RemoteException {
books.add(book);
}
@Override
public void registerBookEvent(IBookCallBackInterface bookEvent) throws RemoteException {
}
@Override
public void unregisterBookEvent(IBookCallBackInterface bookEvent) throws RemoteException {
}
}
3、拷貝一份IBooksAidlInterface.aidl到用戶端,注意用戶端的IBooksAidlInterface.aidl和服務端的必須完全一緻,包括包名和源代碼。
4、用戶端連結服務,并且通過服務端傳過來的IBinder轉換成IBooksAidlInterface對象。
//BookClient .java
package com.example.wangqiubo.myapplication;
import android.content.ComponentName;
import android.content.ServiceConnection;
import android.os.IBinder;
import com.example.wangqiubo.myaidl.IBooksAidlInterface;
/**
* Created by kingsoft on 2017/11/22.
*/
public class BookClient {
IBooksAidlInterface book;
public ServiceConnection connection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service{
book = IBooksAidlInterface.Stub.asInterface(service);
}
@Override
public void onServiceDisconnected(ComponentName name) {
}
};
}
5、用戶端拿到IBooksAidlInterface 對象,則就可以直接調用裡面的方法了,其最後調用的就是在伺服器端實作IBooksAidlInterface 類的方法。這裡有一點需要注意,調用伺服器的方式的時候,必須開區一個線程,在非UI線程中來擷取結果。原因很簡單,android如果5秒沒反應就會出現ANR,因為是通過網絡通路伺服器的,是以得到結果的時間是未知的,并且調用伺服器的方法時用戶端會進行等待式阻塞,直到伺服器的回應。
以上代碼結構截圖如下:
