天天看點

AIDL詳解之AIDL基礎

本技術博文計劃分為三個系列:

一、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,因為是通過網絡通路伺服器的,是以得到結果的時間是未知的,并且調用伺服器的方法時用戶端會進行等待式阻塞,直到伺服器的回應。

以上代碼結構截圖如下:

AIDL詳解之AIDL基礎
AIDL詳解之AIDL基礎