IPC机制(一)

2018-12-11  本文已影响0人  熊出没之大熊快跑

1:Android IPC简介

IPC是inter-Process Communication的缩写,含义为进程间通信或者跨进程通信,是指两个进程之间进行数据交换的过程。

问题:什么是线程?什么是进程?

答:1)线程是CPU调度的最小单位,同时线程是一种有限的系统资源;

       2)进程一般指一个执行单元,在PC和移动设备上指一个程序或者一个应用;

       3)一个进程一般可以包含多个线程,因此进程和线程是包含与被包含的关系。一个进程中可以只有一个线程,即主线程(在Android里面,主线程也叫UI线程,在UI线程里才能操作界面元素)。

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

       IPC不是Android中独有的,任何一个操作系统都需要相应的IPC机制 ,比如Windows上可以通过剪贴板、管道和邮槽等来进行通信;Linux上可以通过命名的管道、共享内存、信号量等来进行通信。可以看到不同的操作系统平台有着不同的进程间通信方式,对于Android来说,它是一种基于Linux内核的移动操作系统,它的进程间通信方式并不完全继承自Linux,相反的,它有自己的进程间通信方式。在Android中最有特色的进程间通信方式就是Binder了,通过Binder可以轻松的实现进程间通信,除了Binder,Android还支持Socket,通过Socket也可以实现任意两个终端之间的通信,当然,一个设备上的两个进程通过Socket通信自然也是可以的。

2.Android 中的多进程模式

       多进程的情况分为两种:1.一个应用因为某些原因(比如有些模块由于特殊原因需要运行在单独的进程中,又或者为了加大一个应用可使用的内存所以需要通过多进程来获取多分内存空间)自身需要采用多进程模式来实现。Android对单个应用所使用的最大内存做了限制。2.当前应用需要向其他的应用获取数据,由于是两个应用,所以必须采用跨进程的方式来获取所需的数据,甚至我们通过系统提供的ContentProvider去查询数据的时候,其实也是一种进程间通信,只不过通信细节被系统内部屏蔽了,我们无法感知而已。总之,不管出于何种原因,我们采用了多进程的设计方法,那么应用中就必须妥善地处理进程间通信的各种问题。

        通过给四大组件指定android:process属性,我们可以轻易地开启多进程模式,着开起来很简单,但是实际使用过程却暗藏先机,多进程远远没有我们想的那么简单,有时候我们通过多进程得到的好处甚至都不足以弥补使用多进程所带来的代码层面的负面影响。

2.1 开启多进程模式

       正常情况下,在Android中多进程是指一个应用中存在多个进程的情况,因此这里不讨论两个应用之间的多进程情况。首先,在Android中使用多进程只有一种方法,那就是给四大组件(Activity、Service、Receiver、ContentProvider)在AndroidMenifest中指定android:process属性,除此之外没有其他的办法,也就是说我们无法给一个线程或者一个实体类指定其运行时所在的进程。其实还有另一种非常规的多进程方法,那就是通过JNI在native层去fork一个新的进程,但是这种方法属于特殊的情况,也不是常用的创建多进程的方式,因此我们暂时不考虑这种方式。

私有进程实现 公有进程实现 私有进程和共有进程的区别

        我们知道Android为每个应用分配了一个独立的虚拟机,或者说为每个进程都分配了一个独立的虚拟机,不同的虚拟机在内存分配上有不同的地址空间,这就导致在不同的虚拟机中访问同一类的对象会产生多个副本。比如,在进程A和进程B中都存在一个UserManager类,并且这两个类是互不干扰的,在一个进程中修改sUserId只会影响当前进程,对其他的进程不会造成任何影响。所有运行在不同进程中的四大组件,只要它们之间需要通过内存来共享数据,都会共享失败,这也是多进程所带来的主要影响!一般来说,使用多进程会造成如下几方面的问题:

1)静态成员和单例模式完全失效。

2)线程同步机制完全失效。

3)sharedPreference的可靠性下降。

4)Application会多次创建。

       关于1、2,既然都不是一块内存了,那么不管是锁对象还是锁全局类都无法保证线程同步,因为不同进程锁的不是一个对象。关于第3个问题是因为SharePreference不支持两个进程同时去执行写操作,否则会导致一定几率的数据丢失,这是因为SharedPreference底层是通过读/写XML文件来实现的,并发写显然是可能出问题的,甚至并发读/写都有可能出问题。第4个问题,运行在同一个进程中的组件是属于同一个虚拟机和同一个Application的,同理,运行在不同进程中的组件是属于两个不同的虚拟机和Application的。

        在多进程模式中,不同进程的组件的确会拥有独立的虚拟机、Application以及内存空间,这会给实际开发带来很多困恼。我们也可以这么理解同一个应用间的多进程:它就相当于两个不同的应用采用了SharedUID的模式,这样能够更加直接地理解多进程模式的本质。系统提供了很多跨进程通信的方法,虽然说不能直接地共享内存,但是通过跨进程通信我们还可以实现数据交互。实现跨进程通信的方式很多,比如通过Intent来传递数据,共享文件和SharedPreference,基于Binder的Messenger和AIDL以及Socket等。

参考:Android 开发艺术探索

Android多进程总结一:生成多进程(android:process属性)

https://blog.csdn.net/lixpjita39/article/details/77435156

上一篇下一篇

猜你喜欢

热点阅读