Android-多進程初識

Android-多進程初識

學習自

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

進程與線程

IPC(Inter-Process Communication)指的是進程間通訊,指的是兩個進程之間交換數據的過程。在學習IPC以前咱們得先了解一下什麼是進程,什麼是線程。android

進程是應用程序的實例,是操做系統進行資源分配和調度的最小單元,每一個進程都表明着應用的一個實例git

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

一個進程最少包括一個線程(UI線程),可是若是在UI線程中執行大量耗時的操做的話,那麼就會形成UI無響應。固然這是不可取的。併發

採用多進程的好處

雖然使用了多進程之後在數據通訊方面變的比較繁雜而且可能會遇到各類各樣的問題,可是多進程也有本身的好處。衆所周知Android的每一個應用程序能夠調用的內存是有限制的,可是若是分配的內存不夠咱們的應用程序的話,那麼咱們就能夠經過多進程的方式來獲取更多的內存資源。app

還有若是咱們的應用程序若是須要一些獨立的模塊的話,也須要採用多進程。ide

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 文件中爲四大組件指定進程便可。
調用Activitythis

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.studyipc
u0_a84    4039  1377  1415804 49424 SyS_epoll_ 00000000 S top.littledavid.studyipc:remote
u0_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的基礎。

相關文章
相關標籤/搜索