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通信!