android進程間通訊(2)--Binder解析及AIDL的使用

android進程間通訊(2)–理解Binder及AIDL使用

前言:之前一篇文章記錄了Bundle和文件共享的方式來進行進程間通訊,但并不是所有場景都適用的,比如A進程正在進行一個計算,計算完成后要啟動B進程并把計算結果傳遞給B進程,但是計算結果不支持放入Bundle,又或者A進程有個封裝好的方法,B進程想要調用A進程里面的方法,使用Bundle則行不通了。因此android提供了一種進程間通訊方式Binder。Binder是Android系統(tǒng)最主要的IPC方式,其中Messenger,AIDL,ContentProvider底層實現(xiàn)都是Binder。由于Binder的實現(xiàn)比較復雜,這里只記錄基本原理。

1.Binder機制

了解binder首先要解決幾個疑問:1.什么是Binder? 2.Binder的實現(xiàn)原理?3.Binder的具體應用有哪些?

(1).什么是binder

直觀來說,Binder是android中的一個類,它實現(xiàn)了IBinder接口。從IPC角度說,Binder是android中的一種跨進程通訊方式。Binder可以理解為一種虛擬的物理設備,它的設備驅動是/dev/binder,該通訊的方式在Linux中沒有。從Android Framework角度來說,Binder是ServiceManager連接各種Manager比如ActivityManager,WindowManager,InputManager,ResourceManager等等和相應的ManagerService的橋梁。從安卓應用層來說,Binder是客戶端和服務端進行通訊的媒介。

(2).Binder實現(xiàn)原理

個人覺得想要理解Binder的實現(xiàn)原理,首先要理解以下兩個方面的東西。1.Android的體系架構;2.計算機的內存管理。

<1>.Android體系架構

首先來看一下android架構圖,圖片來自網(wǎng)絡。


image

1.內核層:Linux 內核和各類硬件設備的驅動,binder驅動/dev/binder位于這一層
2.類庫層:由于類庫層多是c/c++編寫的native代碼,所以又叫C庫層
3.應用程序框架層:這一層可以理解為 Android SDK,提供四大組件,View 繪制體系等平時開發(fā)中用到的基礎部件,因為該層主要是java編寫,所以又叫java庫層
4.應用層:開發(fā)人員開發(fā)的應用程序層
其實在內核層和類庫層還有一層是HAL,硬件抽象層:封裝「內核層」硬件驅動,提供可供「系統(tǒng)服務層」調用的統(tǒng)一硬件接口

<2>計算機內存管理

1.早期的機器并沒有任何的虛擬地址的概念,被稱為“實模式”內存管理。而后期發(fā)展出來的設備提供了虛擬地址的硬件實現(xiàn)。最早的操作系統(tǒng)中,并沒有嚴格意義的內存保護機制,對于內存的訪問約束完全在于程序編寫者的自覺性,這種做法并不靠譜。為了管理內存和保護內存,提出了虛擬內存和進程概念。虛擬內存是一個抽象的概念,它為每個進程提供了一個假象,即每個進程都在獨占的使用主存,每個進程看到的內存都是一致的,稱為虛擬地址空間。如下圖所示,在Linux中,地址空間的最上面區(qū)域是保留給操作系統(tǒng)的代碼和數(shù)據(jù)的,這對所有進程來說都一樣,地址空間的底部區(qū)域存放用戶進程定義的代碼和數(shù)據(jù)。


VmYUGfo.png

也正是因為這樣,每個進程都有自己獨立的內存空間,沒有辦法直接訪問它管轄以外的內存空間,所以進程間通訊要通過系統(tǒng)提供的IPC方式進行通訊。而Binder則是android上主要的IPC方式。

從內存訪問的角度來看,Binder的作用就是讓兩個進程可以訪問同一塊內存空間,實現(xiàn)數(shù)據(jù)交換,如圖:圖片來自http://gityuan.com/2015/10/31/binder-prepare/

C0ddZIP.png

每個Android的進程,只能運行在自己進程所擁有的虛擬地址空間。對應一個4GB的虛擬地址空間,其中3GB是用戶空間,1GB是內核空間,當然內核空間的大小是可以通過參數(shù)配置調整的。對于用戶空間,不同進程之間彼此是不能共享的,而內核空間卻是可共享的。Client進程向Server進程通信,恰恰是利用進程間可共享的內核內存空間來完成底層通信工作的,Client端與Server端進程往往采用ioctl等方法跟內核空間的驅動進行交互

<3>Binder實現(xiàn)機制

Android系統(tǒng)Binder機制中的四個組件Client、Server、Service Manager和Binder驅動程序的關系如下圖所示:


image

1. Client、Server和Service Manager實現(xiàn)在用戶空間中,Binder驅動程序實現(xiàn)在內核空間中
2. Binder驅動程序和Service Manager在Android平臺中已經(jīng)實現(xiàn),開發(fā)者只需要在用戶空間實現(xiàn)自己的Client和Server
3. Binder驅動程序提供設備文件/dev/binder與用戶空間交互,Client、Server和Service Manager通過open和ioctl文件操作函數(shù)與Binder驅動程序進行通信
4. Client和Server之間的進程間通信通過Binder驅動程序間接實現(xiàn)
5. Service Manager是一個守護進程,用來管理Server,并向Client提供查詢Server接口的能力

2.Binder具體應用

從Binder的實現(xiàn)機制可以知道,使用Binder需要創(chuàng)建Client(客戶端)和Server(服務端)。應用層使用Binder進行進程間通訊具體實現(xiàn)有Messenger,AIDL,ContentProvider,由于Messenger底層是AIDL,Contentprovider涉及到數(shù)據(jù)庫。這里只記錄AIDL的使用方式。

服務端創(chuàng)建:
步驟1.首先新建一個工程,并在app的module的mian文件下創(chuàng)建文件夾aidl,如圖:


image

步驟2:創(chuàng)建.aidl文件,如圖中的hdcPearAIDL.aidl文件,并添加兩個方法,hdcPearAIDL.aidl內容如下:

 package pear.cn.hdcsdktest;
   interface hdcPearAIDL {
        void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat,
           double aDouble, String aString);
        int add(int a,int b);
        void shellCommand(String cmd);
    }

build項目之后會在build>generated->source->aidl->debug->下面生成hdcPearAIDL的java文件,這文件是系統(tǒng)自動生成的,如下圖:


DjISWbB.png

步驟3.創(chuàng)建服務并注冊,如下圖:

image

服務內容如下,AidlService繼承Service,重寫onBind()方法,并返回IBinder的實例。并在iBinder里面實現(xiàn)接口定義的方法,提供給其他進程調用。

/**
   * Created by hdc on 2016/11/28.
   *
   */

    public class AidlService extends Service {
        @Nullable
        @Override
     public IBinder onBind(Intent intent) {
            return iBinder;
    }
    private IBinder iBinder = new hdcPearAIDL.Stub() {
        @Override
        public void basicTypes(int anInt, long aLong, boolean aBoolean,
         float aFloat, double aDouble, String aString) throws RemoteException {

        }

        @Override
        public int add(int a, int b) throws RemoteException {
            LogUtil.i("hdcTest"," use the method "+a+"/"+b);
            return a+b;
        }

        @Override
        public void shellCommand(String cmd) throws RemoteException {
            LogUtil.i("hdcTest"," use the method shellCommand "+cmd);
            ShellUtil.execCommand(cmd,ShellUtil.checkSuRoot());
        }
    };
}

別忘記在AndroidManifest中注冊AidlService。

    <service android:name=".services.AidlService">
        <intent-filter>
            <action android:name="pear.cn.hdcsdktest.services.AidlService"/>
        </intent-filter>
     </service>

客戶端創(chuàng)建:
步驟1:同樣在app的module的mian文件夾下面創(chuàng)建aidl文件夾和相同包名,相同名字的aidl文件,可以將服務端的aidl文件直接copy過來,如下圖:


image

步驟2:綁定服務,在客戶端的activity的onCreate方法里面綁定服務,在onServiceConnected()方法返回hdcPearAIDL對象,可以使用aidl對象來調用服務端的方法。

 public class MainActivity extends AppCompatActivity {

    private hdcPearAIDL aidl;

    private ServiceConnection serviceConnection =new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            aidl= hdcPearAIDL.Stub.asInterface(service);
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            aidl=null;
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        bindService();
    }

    private void bindService() {

        Intent intent = new Intent();
        //綁定服務端的service
        intent.setAction("pear.cn.hdcsdktest.services.AidlService");
        //新版本(5.0后)必須顯式intent啟動 綁定服務
        intent.setComponent(new ComponentName("pear.cn.hdcsdktest","pear.cn.hdcsdktest.services.AidlService"));
        //綁定的時候服務端自動創(chuàng)建
        bindService(intent,serviceConnection, Context.BIND_AUTO_CREATE);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        unbindService(serviceConnection);
    }
}

總結

1.Binder是android中最主要的IPC方式
2.Binder實現(xiàn)原理涉及到android框架體系以及操作系統(tǒng)的內存管理機制
3.Messager,AIDL,ContentProvider的底層原理是Binder

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 178,872評論 25 709
  • Android跨進程通信IPC整體內容如下 1、Android跨進程通信IPC之1——Linux基礎2、Andro...
    隔壁老李頭閱讀 12,464評論 11 56
  • 一個人的奮斗應該是這樣的 你有過拿自己和別人做比較,然后感到慌張、惆悵嗎?你有過把自己最寶貴的時間浪費在錯誤的人身...
    水哥1022閱讀 386評論 0 0
  • “老師,出上海了嗎……?” “老師,到浙江了啊?……” 對于這群嘰嘰喳喳的孩子們而言,一路抑制不住的興奮和激動。是...
    陽光Sunflower閱讀 502評論 0 4
  • 為什么需要大數(shù)據(jù)? 為什么現(xiàn)在要提出大數(shù)據(jù)的概念如果我是公司的CEO為什么要關心大數(shù)據(jù)? 大數(shù)據(jù)預示著一場新的革命...
    付大寶慧慧閱讀 230評論 0 0

友情鏈接更多精彩內容