天天看點

android跨程序通信(IPC)——AIDL

轉載請标明出處:

http://blog.csdn.net/sinat_15877283/article/details/51026711;

本文出自: 【溫利東的部落格】

最近在看 @任玉剛 大神編寫的《android開發藝術探索》,讓我受益良多,以此來鞏固一下我的學習成果。下面我将從一下幾個方面寫一下我對AIDL的一些簡單認識。

android跨程式通信(IPC)——AIDL

AIDL 簡單概念

什麼是AIDL呢?AIDL的Android官方定義如下:

AIDL (Android Interface Definition Language) is similar to other IDLs you might have worked with. It allows you to define the programming interface that both the client and service agree upon in order to communicate with each other using interprocess communication (IPC). On Android, one process cannot normally access the memory of another process. So to talk, they need to decompose their objects into primitives that the operating system can understand, and marshall the objects across that boundary for you. The code to do that marshalling is tedious to write, so Android handles it for you with AIDL.

AIDL(Android Interface Definition Language,Android 接口定義語言) Android系統平台的接口定義語言與您可能已經使用過的其他IDLs接口定義語言相似。程式員可以利用AIDL自定義程式設計接口,在用戶端和服務端之間實作程序間通信(IPC)。在Android平台上,一個程序通常不能通路另外一個程序的記憶體空間,是以,Android平台将這些跨程序通路的對象分解成作業系統能夠識别的簡單對象, 并且為跨應用通路而特殊編排和整理這些對象。用于編排和整理這些對象的代碼編寫起來非常冗長,是以Android的AIDL提供了相關工具來自動生成這些代碼供程式員使用。

AIDL的作用

如果在一個程序中(例如Activity)要調用另一個程序中(例如Service)對象的操作,就可以使用AIDL生成可序列化的參數。

AIDL IPC機制是面向接口的,像COM或Corba一樣,但是更加輕量級。它是使用代理類在用戶端和實作端傳遞資料。

AIDL的使用場合

隻有你允許用戶端從不同的應用程式為了程序間的通信而去通路你的service,以及想在你的service處理多線程。如果不需要進行不同應用程式間的并發通信(IPC),

you should create your interface by implementing a Binder

;或者你想進行IPC,但不需要處理多線程的,則

implement your interface using a Messenger

參考:IPC、Binder、AIDL與Intent之間差別與聯系

AIDL的使用

服務端

首先要建立一個Service用來監聽用戶端的連接配接請求,然後建立一個AIDL檔案,将暴露給用戶端的接口在這個AIDL檔案中說明,最後在Service中實作這個AIDL接口即可。

用戶端

要做的事情:綁定服務端的Service,綁定成功後,将服務端傳回的Binder對象轉化成AIDL接口所屬的類型,接下來就可以調用AIDL中的方法了。

具體AIDL的使用方法我也就不在重新造輪子了,請參考:使用AIDL

需要掌握的知識點

  • binder的基本使用與原理
  • Service的基本使用:Android 中的 Service 全面總結
  • AIDL支援的資料類型
    • 基本資料類型(int、long、char、boolean、double等)
    • String和CharSequence
    • List:隻支援ArrayList,裡面每個元素都必須被AIDL支援;
    • Map:隻支援HaspMap,裡面每個元素都必須被AIDL支援,包括key和value;
    • Parcelable:所有實作了Parcelable接口的對象
    • AIDL:所有AIDL接口本身也可以在AIDL檔案中使用
  • CopyOnWriteArrayList (支援并發讀寫)
  • RemoteCallBackListb(删除跨程序listener的接口)
  • 如何開啟多程序:http://blog.csdn.net/sinat_15877283/article/details/50824639

注意點

  • AIDL包結構需要在服務端和用戶端保持一緻
    android跨程式通信(IPC)——AIDL
  • Parcelable對象必須要有同名的AIDL檔案
android跨程式通信(IPC)——AIDL
  • 應該加入權限驗證

    預設情況下,我們的遠端服務任何人都可以連接配接,但這應該不是我們願意看到的,是以我們必須給服務加入權限驗證功能,權限認證失敗則無法調用服務中的方法。

    • Service.onBind方法中進行權限認證
    • Binder.Stub(){ void onTransact() } 方法内進行權限認證
public class XxxService extends Service {
      .....
    private Binder mBinder = new IBookManager.Stub() {
        //在這裡可以做權限認證,return false意味着用戶端的調用就會失敗
        @Override
        public boolean onTransact(int code, Parcel data, Parcel reply, int flags) throws RemoteException {
        // todo 驗證條件
            return super.onTransact(code, data, reply, flags);
        }
        ......
    };


    @Override
    public IBinder onBind(Intent intent) {
        // todo 驗證條件
        return mBinder;
    }
    ......
}
           
  • 注意使用線程,避免ANR程式無響應

最後附上我的demo(暫時沒有稽核通過,有需要的可以先給我留郵箱),

demo内除了簡單的實作了用戶端與服務端之間的程序通信,

還添加了服務端對用戶端連接配接的權限認證,以及有效的解除用戶端對服務端的監聽注冊。

參考:http://book.51cto.com/art/201212/374958.htm

http://www.cnblogs.com/over140/archive/2011/03/08/1976890.html

http://blog.csdn.net/singwhatiwanna/article/details/17041691

http://www.cnblogs.com/newcj/archive/2011/05/30/2061370.html

binder: http://blog.csdn.net/cauchyweierstrass/article/details/50701102

繼續閱讀