Android查缺補漏(IPC篇)-- 進程間通訊基礎知識熱身

來源:互聯網
上載者:User

標籤:version   exp   stack   asi   是什麼   proxy   進程間通訊   建議   sock   

本文CodingBlock 文章連結:http://www.cnblogs.com/codingblock/p/8479282.html

在Android中處理序間通訊是比較難的一部分,同時又非常重要,針對處理序間通訊,博主會用四篇文章來介紹,本篇文章為IPC系列的開篇,主要介紹一些IPC中用到的一些概念、基礎等,目的是讓讀者朋友們在學習IPC之前對一些必要的知識有一個大體的把握。在Android中進程間通訊的方式有很多種,在後續的三篇中會分別介紹每一種方式的實現過程已經各自的優缺點。

進程間通訊篇系列文章目錄:

  • Android查缺補漏(IPC篇)-- 進程間通訊基礎知識熱身
  • Android查缺補漏(IPC篇)-- Bundle、檔案分享權限設定、ContentProvider、Messenger四種進程間通訊介紹
  • Android查缺補漏(IPC篇)-- 款進程通訊之AIDL詳解
  • Android查缺補漏(IPC篇)-- 跨進程通訊之Socket簡介及樣本
IPC是什嗎?

IPC(全稱:Inter-Process Communication)為進程間通訊,指至少兩個進程間傳遞資料或訊號的一些技術活方法。

註:進程間通訊是至少兩個進程之間發生的事情,我們通常習慣性的會把一方稱為用戶端,一方稱為服務端,在後續的文章也會多次出現用戶端和服務端,沒接觸過處理序間通訊的童鞋可能一開始會不太習慣,這裡要注意一下。

為什麼要使用IPC?

無論是在電腦系統還是Android系統中每個進程都有自己一部分獨立的系統資源,彼此是隔離的,為了能是不同的進程互相訪問資源並協同工作,就需要用到進程間通訊。

RPC是什嗎?

RPC(Remote Procedure Call)—遠端程序呼叫,它是一種通過網路從遠端電腦程式上請求服務,而不需要瞭解底層網路技術的協議。(-來自百度百科)

在後面介紹AIDL時會用到RPC的概念,在這裡簡要說明一下RPC在Android的進程間通訊所扮演的角色,以博主本人的理解,簡單來說RPC機制就是指在本地即可調用遠程進程中的方法,而不需要關心其底層實現。

在Android中IPC有哪幾種實現方式?
  • Bundle
  • 檔案分享權限設定
  • ContentProvider
  • Messager
  • AIDL
  • Socket
如何開啟一個進程

在四大組件的AndroidManifest配置中配置process屬性

比如這個:

<service    android:name=".messager.MessengerService"    android:exported="true"    android:process=":remote" />

“:”開頭和不帶“:”的有什麼區別:

“:”開頭的進程屬於當前應用的私人進程,其他應用的組件不能和它跑在同一進程下。
不帶“:”的進程屬於全域進程,其他應用可以通過ShareUID和它跑在同一進程下。

Android系統會為每一個應用程式指派一個UID,具有相同的UID才能共用資料。
通過ShareUID跑在同一進程中需要兩個應用有相同的ShareUID並且有相同的簽名才可以。

Android系統為每一個進程分配一個獨立的虛擬機器,不同的虛擬機器在記憶體配置上有不同的地址空間,這就導致不同的虛擬機器訪問同一個類的對象會產生多個副本。

使用多進程會導致如下問題:

  1. 靜態變數和單例失效
  2. 線程同步機制失效
  3. SharePreference可靠性下降
  4. Application多次建立
IPC中涉及到的基礎概念
  • Serializable
  • Parcelable
  • Binder
Serializable

使用Serializable進行序列化很簡單,只需要實現Serializable介面,然後為類指定一個serialVersionUID即可。

Serializable中的serialVersionUID工作機制:

  1. 序列化時系統會把當前類的serialVersionUID寫入序列化的檔案中(或其他中介)
  2. 還原序列化時系統去檢測檔案中的serialVersionUID,對比是否和當前類的seralVersionUID一致。
  3. 一致就說明序列化的類的版本和當前類的版本是相同的,可以成功還原序列化,否則就說明當前類和序列化的類相比發生了某些轉換,就會報錯(java.io.InvalidClassException)
  • 靜態變數屬於類不屬於對象,不參與序列化過程
  • 用transient關鍵字標記的成員變數不參與序列化過程
Parcelable

使用Parcelable進行序列化比Serializable要麻煩一些,需要實現Parcelable介面,並實現一些必要方法,其通常形式如下:

public class Contact implements Parcelable {    public int phoneNumber;    public String name;    public String address;    public Contact(int phoneNumber, String name, String address) {        this.phoneNumber = phoneNumber;        this.name = name;        this.address = address;    }    public Contact() {    }    @Override    public int describeContents() {        return 0;    }    @Override    public void writeToParcel(Parcel dest, int flags) {        dest.writeInt(phoneNumber);        dest.writeString(name);        dest.writeString(address);    }    public void readFromParcel(Parcel parcel) {        phoneNumber = parcel.readInt();        name = parcel.readString();        address = parcel.readString();    }    public final static Creator<Contact> CREATOR = new Creator<Contact>() {        @Override        public Contact createFromParcel(Parcel source) {            return new Contact(source);        }        @Override        public Contact[] newArray(int size) {            return new Contact[size];        }    };    public Contact(Parcel parcel) {        phoneNumber = parcel.readInt();        name = parcel.readString();        address = parcel.readString();    }}

一個類只要實現了Parcelable介面,其對象就可以實現序列化並可以通過Intent和Binder傳遞。

  • Parcelable中的Parcel內部包含了可序列化的資料,可以在Binder中自由傳輸。
  • 序列化功能:writeToParcel實現,最終是通過Parcel中的一系列write方法完成。
  • 還原序列化:CREATOR完成,通過Parcel的一系列read方法來完成,內部表明了如何建立序列化對象和數組。
  • 內容描述:describeContents:僅噹噹前對象中存在檔案描述符時返回1,其餘所有情況返回0。
  • 還原序列化過程需要傳遞當前線程的上下文類載入器,否則會報找不到類的錯誤。
Serializable和Parcelable的區別:
  • Serializable是java中的序列化介面,使用簡單,但開銷很大,序列化和還原序列化過程需要大量IO操作。
  • Parcelable是Android中的介面,使用麻煩,但效率高,首選。
  • Parcelable主要適用於記憶體序列化上,但通過Parcelable將對象序列化到裝置中或序列化後通過網路傳輸也可以,但稍微複雜,建議這種情況用Serializable。
Binder的使用及上層原理
  • Binder是Android中的一個類,實現了IBinder介面
  • 從IPC角度來說,Binder是一種跨進程通訊方式
  • 從android framework角度來說,Binder是ServiceManager連結各種Manager(ActvitiyManager、WindowManager等等)和相應ManagerService的橋樑;
  • 從android應用程式層來說,Binder是用戶端和服務端進行通訊的媒介,當bindService時,服務端會返回一個包含了服務端業務調用的Binder對象

AIDL中自動產生的Binder介面類的一些方法:

  1. DESCRIPTOR:Binder的唯一標識,一般用類名
  2. asInterface(IBinder obj):用於將服務端的Binder對象轉換成用戶端所需的AIDL介面類型的對象。(如果用戶端和服務端位於同一進程,此方法返回的就是服務端的Stub對象本身,否則返回Stub.proxy)
  3. asBinder:返回當前的Binder對象
  4. onTransact:運行在服務端的Binder線程池中

Binder運行在服務端進程,如果服務端進程被異常終止,Binder連結就會斷裂,導致我們遠程調用失敗。但是此時我們並不知道Binder連結已經中斷,為瞭解決這個問題,Binder中提供了兩個配對的方法:

  • linkToDeath:通過它可以給Binder設定一個死亡代理,當Binder死亡後我們就會收到通知。
如何設定Binder死亡代理:

首先聲明一個DeathRecipeint對象,然後通過binder.linkToDeath()方法將其綁定到binder上。在DeathRecipeint內部有一個方法binderDied,當Binder死亡後,系統就會回調binderDied方法。

範例程式碼如下:

private ServiceConnection serviceConnection = new ServiceConnection(){        @Override        public void onServiceConnected(ComponentName name, IBinder service) {            mIContactsManager = IContactsManager.Stub.asInterface(service);            Log.i(TAG, "onServiceConnected: mIContactsManager=" + mIContactsManager);            try {                // 給service設定死亡代理                service.linkToDeath(mDeathRecipient, 0);            } catch (RemoteException e) {                e.printStackTrace();            }        }        ...};private IBinder.DeathRecipient mDeathRecipient = new IBinder.DeathRecipient() {        @Override        public void binderDied() {            // 當binder掛掉後就會執行此方法            if (mIContactsManager == null) {                return;            }            // 首先移除之前綁定的死亡代理            mIContactsManager.asBinder().unlinkToDeath(mDeathRecipient, 0);            mIContactsManager = null;            // 然後重新綁定遠程服務            bindService(intent, serviceConnection, BIND_AUTO_CREATE);        }};

進程間通訊的基礎知識就先介紹到這裡,接下來將開始針對每種進程間通訊方式作出詳細的介紹。

最後想說的是,本系列文章為博主對Android知識進行再次梳理,查缺補漏的學習過程,一方面是對自己遺忘的東西加以複習重新掌握,另一方面相信在重新學習的過程中定會有巨大的新收穫,如果你也有跟我同樣的想法,不妨關注我一起學習,互相探討,共同進步!

參考文獻:

  • 《Android開發藝術探索》
源碼地址:本系列文章所對應的全部源碼已同步至github,感興趣的同學可以下載查看,結合代碼看文章會更好。源碼傳送門

本文CodingBlock 文章連結:http://www.cnblogs.com/codingblock/p/8479282.html

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.