Learn && Live
虚度年华浮萍于世,勤学善思至死不渝
前言
Hey,欢迎阅读Connor学Android系列,这个系列记录了我的Android原理知识学习、复盘过程,欢迎各位大佬阅读斧正!原创不易,转载请注明出处:http://t.csdn.cn/l52O3,话不多说我们马上开始!
1 Android IPC简介
1.1 什么是IPC?
IPC,Inter-Process Communication,进程间通信或跨进程通信,指两个进程之间进行数据交换的过程
1.2 什么是进程?什么是线程?
进程:程序的依次执行过程,或是正在运行的一个程序,动态过程,是程序运行和资源分配的基本单位,系统在运行时会为每个进程分配不同的内存区域。一个程序至少有一个进程,一个进程至少有一个线程
线程:程序内部的一条执行路径,是进程的一个实体,是CPU调度和分派的基本单位,是比程序更小的能独立运行的基本单位。
1.3 多进程场景
(1)一个应用自身需要采用多进程模式来实现,如有些模块由于特殊原因需要运行在单独的进程中、为了加大一个应用可使用的内存而通过多进程来获取多份内存空间(Android对单个应用所使用的最大内存做了限制)
(2)两个不同的应用跨进程获取数据
2 Android 多进程模式
2.1 开启多进程模式
如何开启多进程模式
<activity android:name="com.connor.MainActivity"
android:configChanges="orientation | screenSize"
android:label="@string/app_name"
android:launchMode="standart">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name="com.connor.SecondActivity"
android:configChanges="screenLayout"
android:label="@string/app_name"
android:process=":remote">
</activity>
<activity android:name="com.connor.ThirdActivity"
android:configChanges="screenLayout"
android:label="@string/app_name"
android:process="com.connor.remote">
</activity>
由上面代码可知,声明进程有三种方式:
(1)不指定android:process属性:运行在当前应用默认的进程中,进程名为包名
(2)android:process=“:remote”:创建一个单独进程,进程名为com.connor:remote
(3)android:process=“com.connor.remote”:创建一个单独进程,进程名为com.connor.remote
命名方式的区别
SecondActivity方式:在指定的进程名前附加当前包名,属于当前应用的私有进程,其他应用的组件不可以和它运行在同一个进程中
ThirdActivity方式:完整命名,属于全局进程,其他应用通过沙箱机制可以和它运行在同一个进程中,共享data目录、组件信息、内存数据,两个应用有相同的UID并且签名相同即可共享数据。
2.2 沙箱机制
沙箱机制的本质是为了实现不同应用程序和进程之间的互相隔离。默认情况下,应用没有权限访问系统资源或其他应用的资源。
UserId
每个App和系统进程都被分配唯一并且固定的UserId,这个UID与内核层进程的uid对应,即Android给每个APK进程分配一个单独的用户空间,其Manifest中的UserId对应一个Linux用户都会被分配到一个属于自己的统一的Linux用户ID,并且为它创建一个沙箱,以防影响其他应用程序
全局进程可以通过共享UID方式共享不同应用的数据。但仅仅共享UID就可以了吗?显然不能,还需要两个应用的签名相同。
<manifest ...
android:sharedUserId="com.share">
</manifest>
<manifest ...
android:sharedUserId="com.share">
</manifest>
签名
应用的签名,是为了验证这个应用是否被修改、是否是该应用的所有者发布的等。Android的证书通常是自签名的,也就是开发者可以自己创建的,不需要向CA机构申请。系统认为应用第一次安装时的证书就是合法的。签名有以下几个作用:
(1)应用程序升级:相同包名 + 相同签名才可以覆盖安装。应用市场通常也是通过验证签名来判断是否是应用的所有者
(2)应用程序模块化:允许同一签名的多个应用在一个进程中运行,这些应用即可看成一个程序的各个模块
(3)代码或数据共享:即我们正在讨论的情况,相同的UID + 签名即可共享
(4)安全性校验:使用第三方服务(如微信)会校验应用的签名,签名不对则无法调用。自己的App内也可以增加签名校验(最好放在native中),签名不正确直接退出或报错,防止他人二次打包
2.3 多进程的影响和问题
主要影响
运行在不同进程的Activity无法修改一个类中的static共享数据。
Android为每一个应用分配了一个独立的虚拟机,或者说为每个进程都分配一个独立的虚拟机,不同的虚拟机在内存分配上有不同的地址空间,导致在不同的虚拟机中访问同一个类对象会产生多个副本,修改时实际上修改的是这个数据的拷贝,而非数据本身
主要问题
(1)静态成员和单例模式完全失效。原因见上述的主要影响
(2)线程同步机制完全失效。不同进程锁的不是同一个对象
(3)SharedPreferences的可靠性下降。SharedPreferences不支持两个进程同时去执行写操作,否则会导致一定几率的数据丢失,这是因为SharedPreferences底层是通过读/写XML文件来实现的,并发写显然是可能出问题的,甚至并发读/写都可能出问题
(4)Application会多次创建。当一个组件跑在一个新的进程中时,系统要为这个进程单独分配一个虚拟机,即启动一个应用,自然也会重新创建一个Application