1.IPC 简介
IPC是inter-Process Communication 的缩写,其含义为进程间的通信,是指两个进程之间交换数据的过程。IPC并不是Android中独有的,任何一种操作系统都需要有相应的IPC机制。比如:
| 操作系统 | |
|---|---|
| windows | 剪贴板、管道 、邮槽、Anonymous Pipe(匿名管道)、File Mapping(文件映射)等 |
| Linux | 共享内存、命名管道、信号量等 |
| Android | Binder、Socket、、ContentProvider、消息(Messager)队列 |
2.android 中的多进程模式
通过给四大组件设置android:process属性,我们可以轻易的开启多进程模式,虽然看起来非常简单,但是却有很大的潜在危机。因此一定要慎用。通常情况下,Android中的多进程是指在同一个应用中存在多个进程的情况。
2.1开启多进程的方法一:给四大组件在清单文件也就是AndroidMenifest中指定Android:process属性。我们无法给一个线程或者一个实体类指定其运行时所在的进程。
<activity
android:name="com.byd.byd666.ui.activity.MainActivity"
android:exported="true"
android:screenOrientation="portrait">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name="com.byd.byd666.ui.activity.LoginActivity"
android:exported="false"
android:screenOrientation="portrait"
android:process=":remote">
</activity>
<activity
android:name="com.byd.byd666.ui.activity.RegisterActivity"
android:exported="false"
android:screenOrientation="portrait"
android:process="com.fuangde.fuangde.ui.activity.remote">
</activity>
如上,上面的例子为LoginActivity和RegisterActivity指定了process属性,并且他们两的属性值不同,这意味着当前应用又增加了两个新进程。若当前应用的包名为”com.byd.byd666.ui.activity”,当LoginActivity启动时,系统会为他创建一个单独的进程,进程的名字为”com.byd.byd666.ui.activity:remote”;当RegisterActivity启动时同上,系统会为他创建一个单独的进程,进程的名字为”com.byd.byd666.ui.activity.remote”;同时入口Activity是MainActivity,没有为他指定process属性那么它运行在默认的进程中。默认进程的进程名是包名。
2.2开启多进程的方法二:通过JNI在native层去fork一个新的进程,这种方法较为特殊,并不是常规的创建多进程的方式。
注:使用process属性指定activity在那个进程是时,属性的写法有两种方式”:”和”完整包名”,二者的区别为:
1. “:”的含义是指要在当前的进程名之前附加上当前的包名,是一种简写的方式,而另一种方式直接就是完整的命名方式,不会附加包名信息。
2. 进程名一”:”开头的进程属于当前应用的私有进程,其他应用的组件不可以和它跑在同一个进程中,而另一种方式属于全局进程,其他应用通过ShareUID的方式可以和它跑在同一进程中。
3.多进程模式的运行机制
首先引入一个问题:在我们的项目中也许会有这样的需求,就是需要把某些组件放在单独的进程中去运行。也许我们会采用上面的方法,给组件指定相应的process属性。但是这样也许会出现比较奇怪的现象,比如,还是上面的例子。我们新建了一个类,并且其有一个静态属性叫做ID=1,我们在MainActivity将其的值修改为2,打印一下,然后跳转到RegisterActivity,再次打印一下ID,我们会发现,ID的值在MainActivity(ID=2)和RegisterActivity(ID=1)中是不同的,但是静态变量是可以在所有地方共享的,只要有一处修改都会处处同步。为什么会发生这样的现象呢?
原因:RegisterActivity是运行在单独的进程当中,Android为每一个应用(或者说进程)分配了一个独立的虚拟机,不同的虚拟机在内存分配上有不同的地址空间,这就导致在不同的虚拟机中访问同 一个类的对象会产生多个副本,也就是说在MainActivity和RegisterActivity中都有一个新创建类的副本,且二者互不干扰,因此我们修改了MainActivity所在进程类的副本的ID的值,而RegisterActivity所在进程的类的副本的属性ID的值没有变。
因此所有运行在不同进程的四大组件,只要他们之间需要通过内存来共享数据,都会共享失败。
== 使用多进程一般会出现以下几个问题:==
1. 静态成员和单例模式是完全无效的
2. 线程同步模式失效
3. SharePreference的可靠性降低
4. Application会多次创建
1已经分析过了,2的本质和1类似,既然都不是一块内存了,那么不管是锁对象还是锁全局都无法保证线程同步。因为不同的进程锁的不是同一个对象;3是因为SharePreference是不支持两个进程同时去执行写操作的,否则会导致脏数据或者数据丢失。这是因为SharePreference底层是通过读写XML文件来实现的,并发读写显然是会出现问题的。4是因为当一个组件独立运行在某一个进程中的时候,系统要为其分配独立的虚拟机,这个过程就是启动一个应用的过程。因此一定会重新创建新的application。也就是说运行在不同进程中的组件是属于两个不同的虚拟机和不同的application的。
重点理解:我们可以这样理解同一应用间的多进程,他就是相当于不同的应用采用了ShareUID的模式
2004

被折叠的 条评论
为什么被折叠?



