Android——IPC机制(一)

Android——IPC机制

作者:黑衣侠客


前言

本篇博客主要讲解Android中的IPC机制,首先介绍多进程的概念、多进程开发者模式中注意的事项、Android中的序列化机制和Binder、Bundle、文件共享、AIDL、Messager、ContentProvider和Socket等进程间通信的方式,本篇博客持续更新。

一、Android——IPC简介

IPC是Inter-Progress Communication的缩写,译为进程间的通信或是跨进程通信,指的是:两个进程之间进行数据交换的过程
按照操作系统中的描述,线程是CPU调度的最小单元,同时线程是一种有限的系统资源。而进程一般指一个执行单元,在PC和移动设备上指一个程序或者一个应用。一个进程可以包括多个线程,因此进程和线程是包含与被包含的关系。一个进程中可以只有一个线程,即主线程,在Android里面主线程也叫UI线程,在UI线程里才能操作界面元素

很多时候,一个进程中需要执行大量的耗时任务,如果这些任务放在主线程中去执行,就会造成界面无法响应,严重影响用户体验,这种情况在PC系统和移动系统中都存在,在Android中有一个特殊的名字叫做ANR(Application Not Responding)即应用无响应。

解决这个问题就需要用到线程,把一些耗时的任务放在线程中即可。
IPC不是Android中所独有的,任何一个操作系统都需要有相应的IPC机制:
  • Windows可以通过剪贴板、管道、邮槽等来进行进程间通信;
  • Linux上可以通过命名管道、共享内容、信号量等来进行进程间通信;
我们可以看到,不同的操作系统有着不同的进程通信方式,那么对于Android来说,它是一种基于Linux内核的移动操作系统,它的进程间通信方式并不能完全继承自Linux,它有自己独特的进程间通信方式,通过Binder可以轻松地实现进程间通信,除了Binder,Android还支持Socket,通过Socket也可以实现任意两个终端之间的通信,当然,同一个设备的两个进程通过Socket通信自然也是可以的。
那么谈到IPC的使用场景,就必须提到多进程,只有面对多进程这种场景下,才需要考虑进程间的通信。
多进程的情况一般分为两种:
  • 应用因为某些原因自身需要采用多进程模式实现
  • 当前应用需要向其他应用获取数据

二、Android中的多进程模式

谈到这里,我们先复习一下Android的四大组件,Android的四大组件包括(Activity,Service,Receiver,ContentProvider),通常情况下,Android中的多进程是指一个应用中存在多个进程的情况,在Android中使用多进程只有一个办法,那就是给四大组件在AndroidMenifest中指定android:process属性,
Android——IPC机制(一)_第1张图片

这里的SecondActivity和ThirdActivity的android:process属性分别为:remote和com.ryg.chapter_2.remote,那么我们来谈谈这两者的区别。

首先,“:”的含义是指要在当前的进程名前附加上当前的包名,这是一种简写的方法,对于SecondActivity来说,它的完整的进程名为com.ryg.chapter_2:remote , 而对于ThirdActivity中的声明方式,它是一种完整的命名方式,不会附加包名信息;其次,进程名以“:”开头的进程属于当前应用的私有进程,其他应用的组件不可以和它跑在同一个进程中,而进程名不以“:”开头的进程属于全局进程,其他应用通过ShareUID方式可以和它跑在同一个进程中。

Android系统会为每个应用分配一个唯一的UID,具有UID的应用才能共享数据。

而多进程绝非只是仅仅指定了android:process属性那么简单。

我们知道,Android为每一个应用分配了一个独立的虚拟机,或者说为每一个进程分配了一个独立的虚拟机,不同的虚拟机在内存上有不同的地址空间,这会导致在不同的虚拟机中访问的同一个类的对象会产生多份副本。
在正常情况下,四大组件中间不可能不通过一些中间层来共享数据,那么通过简单的指定进程名来开启多进程都会无法正确运行。
只开启process是无法利用多进程来实现共享数据的
一般来说,使用多进程会造成如下一些问题:
  • ① 静态成员和单例模式完全失效
  • ② 线程同步机制完全失效
  • ③ SharedPreferences的可靠性下降
  • ④ Application 会多次创建

① : 在进程1和进程2中,都存在一个类,类中存在静态的变量,而存在于进程1和进程2中的这个类是互不干扰的,在进程1中修改静态变量的值只会影响当前的进程,对其他进程不会有任何的影响。

② : 既然不是一块内存,那么不管是锁对象还是锁全局类都无法保证线程同步,因为不同进程锁不是同一个对象。

③ : SharedPreferences 不支持两个进程同时去执行写操作,否则会导致一定几率的数据丢失,这是因为SharedPreferences底层是通过读/写XML文件来实现的,并发写显然是可能出问题的,甚至并发读/写都有可能出现问题。

④ :当一个组件跑在一个新的进程中的时候,由于系统要在创建新的进程同时分配独立的虚拟机,所以这个过程其实就是启动一个应用的过程。因此,相当于系统又把这个应用重新启动了一遍,既然重新启动了,那么自然会创建Application。

在Android的多进程模式中,不同进程的组件的确会拥有独立的虚拟机、Application以及内存空间。

虽然Android多进程带来了很多的问题,但我们还是可以通过跨程序通信来实现数据交互的,例如:Intent来传递数据,共享文件和SharedPreferences,基于Binder的Messenger和AIDL以及Socket等。

你可能感兴趣的:(Android)