Android-多進程初識

來源:互聯網
上載者:User

標籤:屬性   public   little   top   cat   檔案中   tostring   空間   ring   

Android-多進程初識學習自

《Android開發藝術探索》
https://baike.baidu.com/item/%E8%BF%9B%E7%A8%8B/382503?fr=aladdin#1
56278433

進程與線程

IPC(Inter-Process Communication)指的是處理序間通訊,指的是兩個進程之間交換資料的過程。在學習IPC之前我們得先瞭解一下什麼是進程,什麼是線程。

進程是應用程式的執行個體,是作業系統進行資源分派和調度的最小單元,每個進程都代表著應用的一個執行個體

線程是程式執行的最小單元,線程本身是不佔有資源的(除了維持本身的資源除外),線程與進程貢獻資源。

一個進程最少包括一個線程(UI線程),但是如果在UI線程中執行大量耗時的操作的話,那麼就會造成UI無響應。當然這是不可取的。

採用多進程的好處

雖然使用了多進程以後在資料通訊方面變的比較繁雜並且可能會遇到各種各樣的問題,但是多進程也有自己的好處。眾所周知Android的每個應用程式可以調用的記憶體是有限制的,但是如果分配的記憶體不夠我們的應用程式的話,那麼我們就可以通過多進程的方式來擷取更多的記憶體資源。

還有如果我們的應用程式如果需要一些獨立的模組的話,也需要採用多進程。

Dalvik 虛擬機器

Android系統為每個進程都單獨的分配了一個 Dalvik 不同的虛擬機器在記憶體有不同的記憶體空間。在不同的進程之間訪問相同的類的對象,會建立不同的 副本 。這些副本之間相互獨立,互不干涉。這也是為何如果我們想在多進程的模式在兩個不同的進程之間通過記憶體來共用資料,顯然是不會成功的。如果想要在處理序間通訊就必須要用到IPC技術。

開啟多進程
<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android"    package="top.littledavid.studyipc">    <application        android:allowBackup="true"        android:icon="@mipmap/ic_launcher"        android:label="@string/app_name"        android:roundIcon="@mipmap/ic_launcher_round"        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=".SecondActivity"            android:process=":remote" />        <activity            android:name=".ThirdActivity"            android:process="top.littledavid.studyipc.remote" />    </application></manifest>

四大組件都可以運行在不同的進程中,通過 process 屬性在 manifest 檔案中為四大組件指定進程即可。
調用Activity

class MainActivity : AppCompatActivity() {    override fun onCreate(savedInstanceState: Bundle?) {        super.onCreate(savedInstanceState)        setContentView(R.layout.activity_main)        this.startActivity(android.content.Intent(this, SecondActivity::class.java))    }}class SecondActivity : AppCompatActivity() {    override fun onCreate(savedInstanceState: Bundle?) {        super.onCreate(savedInstanceState)        setContentView(R.layout.activity_second)        startActivity(Intent(this, ThirdActivity::class.java))    }}

在上面的三個Activity中MainActivity沒有指定進程,那麼MainActivity採用的就是預設進程,預設進程的命名就是程式的 包名 ,如果想要修改預設進程,請給 Application 節點通過 process 屬性指定進程。 SecondActivity的進程是 top.littledavid.studyipc:remote ,ThirdActivity的進程是 top.littledavid.studyipc.remote ,當在運行不同的Activity的時候就會建立不同的進程。通過ADB命名或者DDMS都可以查看已經處於運行狀態的進程。

adb shell ps ##查看所有進程### 下面的進程是我們程式的進程u0_a84    4022  1377  1416356 49952 SyS_epoll_ 00000000 S top.littledavid.studyipcu0_a84    4039  1377  1415804 49424 SyS_epoll_ 00000000 S top.littledavid.studyipc:remoteu0_a84    4056  1377  1418396 50172 SyS_epoll_ 00000000 S top.littledavid.studyipc.remote

上面就是我們開啟的進程。其中 top.littledavid.studyipc 是我們的預設進程,而其餘的兩個則使我們新建立的進程。其中除了預設的進程之外,剩下的兩個進程在聲明的時候也不相同,一個是 :remote 一個是 <包名>.remote 。其中 : 有兩個作用

  1. 最明顯的一個: 省略包名,是一種簡寫的方式 ??
  2. 表示當前進程是一個私人的進程,不同通過共用 UID 的方式讓多個應用共用進程
共用進程

在上面我們提到了共用進程這一概念,眾所周知Android是基於Linux系統的,Android系統在使用權限設定上有一下特點:

  • Android是一種多使用者的Linux系統,Android的每一個應用程式都是一個不同的User
  • 預設情況下,系統會用每個應用程式指派一個唯一的Linux使用者Id,系統為檔案設定許可權,只有該使用者才能夠訪問
  • 每一個進程都有有自己的虛擬機器,因此應用與應用的運行都是相互隔離的。

通過這種多使用者的方式限制了每個應用只能訪問與自己相關的組件,而不能訪問不相關的組件,通過可以安排兩個應用共用一個Linux的使用者ID,在這種情況下,他們可以互相訪問彼此的檔案組件等資訊。

驗證進程間沒有共用記憶體空間

兩個Activity MainActivitySecondActivity ,SecondActivity處於另外的一個進程。通過修改一個靜態變數來驗證一下我們的理論。

//將會在兩個Activity中修改i變數,來驗證object ValueHolder {    public var i = 0}class MainActivity : AppCompatActivity() {    override fun onCreate(savedInstanceState: Bundle?) {        super.onCreate(savedInstanceState)        setContentView(R.layout.activity_main)        ValueHolder.i = 1        this.startActivity(android.content.Intent(this, SecondActivity::class.java))    }}class SecondActivity : AppCompatActivity() {    override fun onCreate(savedInstanceState: Bundle?) {        super.onCreate(savedInstanceState)        setContentView(R.layout.activity_second)        Log.e("TAG", ValueHolder.i.toString())        //輸出 0    }}

在上面的代碼中,我們猛一看可能會認為應該輸出 1 ,但是不要忘了,SecondActivity是在另一個進程中的即在兩個不同的虛擬機器中,當在不同的虛擬機器中訪問同一個對象的時候,會產生不同的副本,這些副本之間互不影響,這也就證實了我們上面的理論。

多進程模式造成的影響

因為不同的進程會運行與不同的虛擬機器導致記憶體不共用,會產生以下的影響:

  1. 靜態成員和單例模式完全失效
  2. 線程同步完全失效
  3. SharedPreference 可靠性下降
  4. Application對象會多次建立

①和②造成的原因是一樣的,因為不是同一塊記憶體了所以線程的同步鎖也就不起作用了

③是因為SharedPreference的底層是讀寫XMl檔案,同時並發寫入同一個檔案可能會早成資料的丟失。

④都知道Application類代表的是應用程式的執行個體,所以的原因也很簡單,因為系統會為每一個進程都會建立一個虛擬機器,這一過程也是建立應用程式的執行個體並啟動的過程,所以這也是為何Application會被多次建立。

總結

這一章,我們簡單的瞭解了一下多進程的概念和多進程的影響,在下一章中,我們來學習IPC的基礎。

Android-多進程初識

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.