IPC多進程之完整解析——多進程的定義、多進程的運行模式(1)

PS:近期可能要對IPC,進程間的通信做一個總結,有需要的同學,可以關注我,我會持續更新下去,把IPC解析透徹! 內容比較多,可能要幾篇文章才能寫完!
多進程的解析:
進程間的通信方式就是Binder了,通過Binder可以輕鬆的實現進程間的通信。除了Binder,Android還支持Socket,通過Socket也可以實現任意兩個終端之間的通信,當然同一個設備上的兩個進程,通過Socket也是可以進行通信的。

多進程的情況分爲兩種。第一種是一個應用因爲某些原因自身採取多進程的模式來實現,至於原因很多,比如有些模塊由於特殊原因需要單獨運行在單獨進程中;又或者爲了加大一個應用可使用的內存所以需要多進程來獲取多份儲存空間。另一種情況就是當前應用需要向另一個應用獲取數據,由於是兩個應用所以必須用多進程來實現。

如何設置多進程?只有一個方法,那就是給四大組件在清單文件AndroidMenifest中,設android:process屬性,除此之外沒有其他辦法,所有隻有四大組件纔可以單獨設置進程,也就是沒有單獨給一個線程、類設置進程。

多進程的定義:
<

application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

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

    </application>

上面代碼運行起來會有三個進程,MainActivity默認一個進程,而SecondActivity 和ThirdActivity通過制定process屬性,會再續創建兩個進程。
SecondActivity進程名稱:.com.baoming:remote
ThirdActivity進程名稱 :.com.baoming.remote

細心一點的同學會發現,我在定義屬性peocess時,一個是:remote,另一個是包名.remote。其實是有區別的。區別有兩個方面,首先以”:”的含義是指在當前進程名稱附加上當前進程的包名,這是一個簡寫。ThirdActivity爲完成的輸寫方式,前面不會附加包名信息。其次進程名以”:”開頭的進程屬於當前應用的私有進程。進程不以”:”開頭的,是全局的進程,其他應用通過ShareUID可以和它跑在同一個進程中。

PS:Android系統會爲每一個應用分配一個唯一UID,具有相同UID的應用才能共享數據。這裏需要說明的是兩個應用通過ShareUID跑在同一個進程中是有要求的,需要這兩個應用有相同的ShareUID和簽名相同纔可以。

多進程的運行機制:
代碼舉例說明:
這裏寫圖片描述

我在MainActivity中修改UserManager的flag值爲2。分別在MainActivity和SecondActivity 打印如下:
這裏寫圖片描述

很明顯 一個爲1,一個爲2,看到這裏大家應該明白了多進程帶來的問題了。
給大家說一下原因:
SecondActivity單獨運行在一個進程中,Android爲每一個應用分配了一個獨立的虛擬機,或者說爲每一個進程都分配一個虛擬機,這就導致在不同虛擬機上訪問同一個類的對象會產生好多副本。那我們的例子來說明,在進程.com.baoming:remote和.com.baoming.remote中都有UserManager類,並且這兩個類互不干擾,在一個進程修改flag值,只會影響單獨的進程。
總結:所有運行在不同進程中的四大組件,只要是通過內存分享數據,都會共享失敗,這也是多進程帶來的影響。一般來說造成的問題如下:

1、靜態成員和單例模式失效
2、線程同步機制失效
3、SharedPreferences的可靠性下降
4、Application會被創建多次

第1個問題:已經在上面做了分析。
第2個問題:本質上和第一個問題類似,既然都不是一塊內存了,那麼不管是鎖對象鎖全局類都無法保證線程同步,因爲不同進程鎖的不是同一個對象。
第3個問題:因爲SP不支持兩個進程同時去執行寫操作,否則會導致一 定機率的數據丟失,這是因爲SP底層是通過讀寫XML文件夾實現的,併發寫顯然是可能出問題的,甚至併發讀寫都有可能出問題。
第4個問題:顯而易見當一個組件跑在新的進程中的時候,由於系統要在創建新的進程同時分配獨立的虛擬機,所以這個過程其實就是啓動一個新的應用。因此相當於系統又把這個應用重啓了一遍,既然重啓了,那麼肯定會重新創建一遍Application。這個問題,也可以這樣理解,運行在同一進程中的組件是屬於同一個虛擬機和同一個Application,同理,運行在不同進程中的組件是屬於兩個虛擬機和Application的。

目前爲止,給大家講述了一下多進程的定義,多進程解析、和多進程存在的問題。接下來的文章我會繼續更新,如何實現多進程的更新。實現多進程的通信方式有很多,比如通過Intent,共享文件和SharedPreferences,基於Binder的Messager和AIDL以及Socket等,但是爲了更好的理解各種IPC方式,我們需要先熟悉一些基礎概念,比如序列化相關的Serializable 和 Parcelable接口,以及Binder的概念,熟悉完這些基礎概念之後,再去理解IPC方式就比較簡單了。

下一篇文章我會更新序列化接口,以及Binder概念!!在更新IPC通信!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章