多进程模式
1. 安卓中实现多进程的方法
在安卓中使用多进程只有一种方法,就是给四大组件在 AndroidManifest
中指定 android:process
属性,我们无法给一个线程或者一个实体类指定其运行时所在的进程。还有另外一种非常规的多进程方法,那就是通过 JNI
在 Nativte
层中去 fork
一个新的进程。
<activity
android:name="com.ryg.chapter_2.MainActivity"
android:configChanges="orientation|screenSize"
android:label="@string/app_name"
android:launchMode="standard" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name="com.ryg.chapter_2.SecondActivity"
android:configChanges="screenLayout"
android:label="@string/app_name"
android:process=":remote" />
<activity
android:name="com.ryg.chapter_2.ThirdActivity"
android:configChanges="screenLayout"
android:label="@string/app_name"
android:process="com.ryg.chapter_2.remote" />
上面的示例分别为SecondActivity和ThirdActivity指定了 process
属性,并且它们的属性值不同,这意味着当前应用又增加了两个新进程。假设当前应用的包名为“com.ryg.chapter_2”
,当SecondActivity启动时,系统会为它创建一个单独的进程,进程名为 “com.ryg.chapter_2:remote”
;当ThirdActivity启动时,系统也会为它创建一个单独的进程,进程名为 “com.ryg.chapter_2.remote”
。同时入口Activity是MainActivity,没有为它指定 process
属性,那么它运行在默认进程中,默认进程的进程 名是包名。
示例中两个 android:process 的属性分别为 :remote
和 “com.ryg.chapter_2.remote”
。这两种方式的区别是:
- 以":"开头的进程属于当前应用的私有进程,其他应用的组件不可以和它在同一个进程中。
- 而进程名不以":"开头的进程属于全局进程,其他应用通过
ShareUID
方式可以和它在同一个进程中运行。
安卓系统会为每个应用分配一个唯一的
UID
, 具有相同UID
的应用才能共享数据。两个应用通过ShareUID
运行在同一个进程中是有要求的,需要这两个应用有相同的ShareUID
并且签名相同才可以。在这种情况下,它们可以互相访问对方的私有数据,比如 data目录、组件信息,还可以共享内存数据。或者说看起来就像是一个应用的两个部分。
可以使用以下命令来查看进程: adb shell ps
或者 adb shell ps| grep com.ryg.chapter_2
2. 安卓多进程带来的问题和影响
- 资源隔离与同步问题
静态成员失效:因为每个进程都拥有独立的虚拟机示例,静态变量在内存中是独立存在的。会造成子进程无法读取在主进程的静态变量,无法获取主进程的缓存数据。所以在使用ContentProvider 或者 Sharedpreference的时候需要配合 MODE_MULTI_PROCESS 模式进行跨进程同步.
文件共享冲突: 主进程和子进程同时操作 SQLite 数据库,导致SQLiteDatabaseLockedException, 需要子进程通过IPC机制请求主进程执行(AIDL等)
- 性能与资源开销
Application重复初始化
进程间通信延迟
- 稳定性与内存管理
独立进程崩溃容错
内存分配优化
- 调试与维护
断点调试失效
单例模式失效