Android IPC機制全解析<一>

來源:互聯網
上載者:User

標籤:不同   rman   單例模式   基礎   bind   android中   影響   實用   serial   

概要

  • 多進程概念及多進程常見注意事項
  • IPC基礎:Android序列化和Binder
  • 跨進程常見的幾種通訊方式:Bundle通過Intent傳遞資料,檔案分享權限設定,ContentProvider,基於Binder的AIDL和Messenger以及Socket。
  • Binder串連池
  • 各種處理序間通訊方式的優缺點及適用情境

IPC是 Inter-Process Communication的縮寫,意為處理序間通訊跨進程通訊,是指兩個進程之間進行資料交換的過程。

線程是CPU調度的最小單元,同時線程是一種有限的系統資源。進程一般指一個執行單元,在PC和行動裝置上指一個程式或者一個應用。一個進程可以包含多個線程,因此進程和線程是包含與被包含的關係。最簡單的情況下,一個進程中只可以有一個線程,即主線程,在Android中也叫UI線程。

IPC不是Android中所專屬的,任何一個作業系統都需要相應的IPC機制,比如Windows上可以通過剪貼簿等來進行處理序間通訊。Android是一種基於Linux核心的移動作業系統,它的處理序間通訊方式並不能完全繼承自Linux,它有自己的處理序間通訊方式。

    1. Android中的多進程模式

通過給四大組件指定android:processs屬性可以開啟多進程模式,我們無法給一個線程或一個實體類指定其運行所在的進程。

<activity android:name=".SecondActivity" android:process=":remote"/><activity android:name=".ThirdActivity" android:process="com.example.remote"/>

應用預設的進程是當前包名,以上分別給兩個Activity指定了進程,意味著當前應用又增加了兩個新進程。假設當前應用程式套件名為com.ipc.example,那麼SecondActivity所在的進程為com.ipc.example.remote,“:”的含義是要在當前進程名前面附上當前的包名,而且已“:”開頭的進程屬於當前應用的私人進程,其他應用的組件不可以和它跑在同一進程。不以“:”開頭的進程是全域進程,如指定了ThirdActivity所在的進程為全域進程。

     2.  多進程模式的運行機制

建立UserManager類:

public class UserManager {    public static int sUserId = 1;}

在MainActivity中將sUserId的值修改為2,由於MainActivity在應用預設進程,SecondActivity在指定進程,在SecondActivity中列印sUserId的值會發現sUserId值並沒有變,還是1。

出現這樣的原因是SecondActivity運行在單獨的進程,Android為每個應用程式指派了一個獨立的虛擬機器或者說為每個進程都分配了一個獨立的虛擬機器,不同的虛擬機器在記憶體上都有不同的地址空間,這就導致在不同的虛擬機器中訪問同一個對象會產生多分副本。上面樣本中MainActivity修改了sUserId的值只會影響當前進程,對其他進程不會造成 任何影響。

所有運行在不同進程的四大組件,只要它們之間需要通過記憶體來共用資料都會失敗。一般來說多進程會造成以下幾個問題:

  • 靜態成員和單例模式完全失效
  • 線程同步機制完全失效(不在同一進程,,鎖的不是同一對象,所以不管鎖對象還是鎖全域類都無法保證線程同步)
  • SharePreferences的可靠性下降
  • Application會多次建立(在Application的onCreate()中列印當前進程名證實了同一應用不同進程下,Application會多次建立。這也說明了多進程模式下,不同進程的組件的確會擁有獨立的虛擬機器、Application以及記憶體空間)

     3. Serializable和Parcelable介面

 Serializable和Parcelable可以完成對象的序列化過程,當我們需要通過Intent和Binder傳輸資料時就需要進行序列化,Serializable是Java提供的一個空介面,為對象提供標準的序列化和還原序列化操作。使用簡單但是序列化和反序列都會做大量的I/O讀寫操作,記憶體開銷較大。

Parcelable是Android中的序列化方式,使用稍微複雜,但是效率高。

     4.  Android中的IPC方式:

     4.1: 使用Bundle

四大組件中的其中三個(Activity、Service、Receiver)都是支援在Intent中傳遞Bundle資料,由於Bundle實現了Parcelable介面,所以它可以方便的在不同進程間傳輸。

     4.2:使用檔案分享權限設定

檔案分享權限設定也是一種不錯的處理序間通訊方式,兩個進程通過讀寫同一個檔案來交換資料,比如A進程中把資料寫入檔案,B進程通過讀取這個檔案來擷取資料。但是這種方式也是又一定局限性的,比如並發讀寫的問題會導致我們讀出的資料不是最新的,因此要避免並發讀寫的發生或者考慮使用線程同步來限制多個線程的讀寫操作。基於這樣的問題,檔案分享權限設定方式適合對資料同步要求不高的進程之間進行通訊。

     4.3:使用Messenger

Messenger是一種輕量級的IPC方案,它的底層實現是AIDL,通過Messenger可以在不同進程中傳遞Message對象,在Message中放入我們需要傳遞的資料就可以輕鬆實現資料在進程間傳遞了。

Messenger的使用很簡單,由於它一次處理一個請求,因此在服務端不用考慮線程同步的問題。Messenger實現處理序間通訊大致可以分為以下幾步,分為服務端和用戶端。

  • 服務端進程
    首先需要在服務端建立一個Service來處理用戶端發起的請求,同時建立一個Handler並通過它來建立一個Messenger對象,然後在Service的onBind中返回這個Messenger對象底層的Binder即可。
  • 用戶端進程
    用戶端進程中首先要綁定服務端的Service,綁定成功後用服務端返回的IBinder對象建立一個Messenger,通過這個Messenger就可以向服務端發送類型為Message的訊息了。

 註冊Service,使其運行在單獨的進程,AndroidManifest.xml中配置:

         

Log日誌:

        

在Messenger中進行資料傳遞必須將資料放入Message中,而Messenger和Message都實現了Parcelable介面,因此可以跨進程傳輸。上面的執行個體只是介紹了如何在服務端接受用戶端中發送的請求,但是有時候還需要回應用戶端。每當用戶端發來一條訊息,服務端就自動回複一條“來自服務端的自動回複:訊息已收到”。如果需要客服端能夠回應用戶端,那麼和服務端一樣,在用戶端還需要建立一個新的Messenger,並把這個Messenger對象通過Message的replyTo參數傳遞給服務端,服務端通過這個replyTo參數就可以回應用戶端。

修改後的服務端代碼:

        

修改後的用戶端代碼:

       

     4.4: 使用AIDL

Messenger是以串列的方式處理用戶端的請求,如果有大量的請求同時發送到服務端,服務端仍然只能一個一個處理,此時Messenger就不大合適了,同時Messenger的作用是為了傳遞訊息,且只能傳遞Bundle支援的資料類型,很多時候需要跨進程調用服務端的方法,這時候可以實用AIDL來實現跨進程的方法調用。AIDL也是Messenger的底層實現,因此Messenger本質上也是AIDL,只不過系統作了封裝。實用AIDL進行處理序間通訊的流程分為服務端和用戶端兩個方面,下面分別介紹:

    • 服務端
      服務端首先要建立一個Service用來監聽用戶端的串連請求,然後建立一個AIDL檔案將暴露給用戶端的介面在這個AIDL檔案中聲明,最後在Service中實現這個AIDL介面即可
    • 用戶端
      用戶端要做的事情稍微簡單些,首先綁定服務端的Service,綁定成功後將服務端返回的Binder對象轉成AIDL介面所屬的類型,接著就可以調用AIDL中的方法了
    • AIDL介面的建立
      詳情參考:https://www.zhihu.com/question/21581761

      需要注意的是,如果AIDL檔案中用到了自訂的Parcelable對象,那麼必須建立一個和它同名的AIDL檔案,並在其中聲明為Parcelable類型。上面代碼中我們用到了BookEntity這個類,所以必須建立BookEntity.aidl,然後將BookEntity定義為Parcelable類型。

                

                

    • 服務端的實現

               
運行在獨立進程:

<service android:name=".service.BookManagerService" android:process="com.ipc.example.remote"/>
  • 用戶端實現

              

這是一次完整的使用AIDL實現處理序間通訊,但是遠遠還沒有完,AIDL的複雜性遠不止這些。

待續.....

Sample連結:  https://github.com/NullUsera/IPC

Android IPC機制全解析<一>

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.