Android多进程模式
来源:互联网 发布:森系服装品牌 知乎 编辑:程序博客网 时间:2024/06/05 15:07
Android多进程模式
深入理解下android多进程模式,为后续进程间通讯做个铺垫~
进程可以理解为一个应用,一个进程可以只有一个线程,即主线程,android中称为UI线程,在UI线程中才能操作view控件;通过给四大组件指定android:process可以轻松启动一个新的进程,看似简单却隐藏了不少问题
一、开启多进程
在android中使用多进程只有一种方法,那就是给四大组件(Activity、Service、Receiver、ContentProvider)在AndroidManifest中指定android:process属性,也就是无法给一个线程或者一个实体类指定运行所在的进程。(通过JNI在native层fock一个新进场的方式除外)
来看一个简单的例子:
注册页面SecondActivity和ThirdActivity,并设置android:process属性,如下:
在MainActivity中启动SecondActivity和ThirdActivity,然后使用add shell ps|grep com.rico.multiprocess可以查看运行的进程:
MainActivity没有指定process,默认运行在以包名命名的进程,:remote和com.rico.multiprocess.remote有区别吗?
首先“:”的含义是在当前进程名前附加包名,这是一种简写方式,对于SecondActivity来说,它的完整进程名是:com.rico.multiprocess:remote。其次,进程名以“:”开头属于当前应用的私有进程,其它应用的组件不可以和它跑在同一个进程中,而不以“:”开头的进程属于全局进程,其它应用可以通过shareUID方式和它跑在同一进程中。
二、运行机制
为什么说多进程运行起来会遇到各种奇怪的问题?
public class AppConfig { public static boolean isDebug = false;}
假设在MainActivity中赋值AppConfig.isDebug = true,然后启动SecondActivity,这是在SecondActivity中打印出来的isDebug是true还是false呢?按照正常逻辑,静态变量在整个程序生命周期内都是生效的,一处修改处处共享,也就是SecondActivity中打印的isDebug应该是true才对,结果却相反:
07-22 21:44:27.494 15138-15138/com.rico.multiprocess I/System.out: MainActivity isDebug->true07-22 21:44:27.682 15190-15190/com.rico.multiprocess:remote I/System.out: SecondActivity isDebug->false
上述问题的原因是SecondActivity运行在单独的进程中,android为每一个应用分配一个独立的虚拟机,或者说为每一个进程分配了一个独立的虚拟机,每个虚拟机在内存分配上有不同的地址空间,这就导致在不同虚拟机上访问的类的对象会产生多个副本。也就是AppConfig在不同进程中存在多个副本,修改com.rico.multiprocess进程的AppConfig不会影响到com.rico.multiprocess:remote进程的AppConfig.
通常使用多进程会有如下问题:
(1)静态成员和单例模式完全失效
(2)线程同步失效
(3)SharePreferences的可靠性下降
(4)Application会多次创建
(1)和(2)的很好理解,因为不是同一个类,(3)是因为sharepreference不支持多进程同时执行写操作,否则会导致一定概率数据丢失,因为sharepreference底层通过读写xml实现,并发写显然容易出问题,(4)可以测试下,在Application加入log
public class MyApplication extends Application{ @Override public void onCreate() { super.onCreate(); int pid = android.os.Process.myPid(); String processName = ""; ActivityManager manager = (ActivityManager) getApplicationContext().getSystemService(Context.ACTIVITY_SERVICE); for (ActivityManager.RunningAppProcessInfo process: manager.getRunningAppProcesses()) { if(process.pid == pid) { processName = process.processName; } } System.out.println("processName->"+processName); }}
运行一下,发现每一个进程都启动了一次MyApplicaon
07-22 22:04:07.958 32549-32549/com.rico.multiprocess I/System.out: processName->com.rico.multiprocess07-22 22:04:08.374 32584-32584/com.rico.multiprocess:remote I/System.out: processName->com.rico.multiprocess:remote07-22 22:04:08.588 32619-32619/? I/System.out: processName->com.rico.multiprocess.remote
为了解决多进程带来的问题,系统提供了很多跨进程的通讯方式,比如Intent、共享文件、SharePreferences,基于binder的Messager和AIDL以及socket等,binder的通讯机制可以参考下一遍博客:Android Binder通讯机制
参考书籍 —【Android开发艺术探索】
- Android多进程模式
- Android多进程模式
- Android多进程模式
- Android中的多进程模式
- android中的多进程模式
- android 中的多进程模式
- Android中的多进程模式
- Android中的多进程模式
- Android IPC机制多进程模式
- 6.Android中的多进程模式
- android中的多进程模式(IPC)
- Android IPC机制之开启多进程模式
- IPC机制---02 Android中的多进程模式
- PID,UID,sharedUserId以及Android开启多进程模式
- Android开发艺术探索笔记(4)- 多进程模式
- Android IPC -- 初期(实现多进程模式)
- Android IPC简介之(多进程模式)初识
- java多进程模式
- IPsec技术介绍
- 多重背包
- 活动(Activity)
- 异或密码
- <shader>编程中遇到的问题-too many texture interpolators would be used for ForwardBase pass
- Android多进程模式
- (fzu)Problem I Magic(模拟+后缀匹配)
- Kotlin for Android(七)Kotlin数据类和Gson
- hihocoder1093 SPFA算法模板
- 南师附中集训总结Day4
- Linux下各种错误处理
- 自学PyQuery扎记
- 继承笔记
- 配置Mac的vim,使代码高亮