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的基础。

相关文章
相关标签/搜索