1.如何开启:
给四大组件(Activity、Service、Receiver、ContentProvider)在AndroidManifest.xml中指定"android:process"属性可以在应用内实现多进程。
如果进程名以":"开头,说明该进程属于私有进程,其他应用的组件不可以和它跑在同一个进程中;
如果进程名不以":"开头,则属于全局进程,其它应用通过ShareUID方式可以和它跑在同一个进程中。
2.注意两个进程之间的数据:
Android为每个应用分配了一个独立的虚拟机,或者可以说每个进程都有一个独立的虚拟机,不同的虚拟机在内存分配上有不同的内存地址,这就导致不同的虚拟机访问同一个类的对象会产生多份副本。
所以,所有运行在不同进程中的四大组件,只要他们之间通过内存来共享数据,都会共享失败。
一般来说,使用多进程会有以下影响:
<1>.静态成员和单例模式完全失效
<2>.线程同步机制完全失效(因为都不是一块内存了,所以不同进程锁都不是同一个对象)
<3>.SharePreferences的可靠性下降(因为SharePreferences不支持两个进程同时进行写操作,会导致一定几率的数据丢失,这是因为SharePreferences底层是通过读写xml来实现的)
<4>.Application会多次创建
3.进程间通信
进程获取的内存空间是一块抽象的内存,然后会映射到实际的某一块物理内存,因此,每个进程都无法访问其他进程在内存里面数据。
不同进程之间的通信,就意味着在两块不同的物理内存间传递数据
当然,原生的数据,比如int或者String数据都是可以传递的,但是对象数据是不可以的
在Android中,最有特色的进程间通信方式就是Binder了,还可以支持Socket(既可以在两个设备之间Socket通信,也可以在一个设备的不同进程间通信)。
1 SharedPreferences myPrefs = context.getSharedPreferences(MY_FILE_NAME, Context.MODE_MULTI_PROCESS | Context.MODE_PRIVATE);
一旦我们设置了这个Flag,每次调用Context.getSharedPreferences 的时候系统会重新从SP文件中读入数据,因此我们在使用的时候每次读取和存入都要使用Context.getSharedPreferences 重新获取SP实例。即使是这样,由于SP本质上并不是多进程安全的,所以还是无法保证数据的同步,因此该方法我们并没有使用,我们也不推荐使用。
由于SP不是多进程安全的,可以使用一个多进程安全的开源项目:Tray (但是需要的minsdk是15)
1 // create a preference accessor. This is for global app preferences. 2 final AppPreferences appPreferences = new AppPreferences(getContext()); // this Preference comes for free from the library 3 // save a key value pair 4 appPreferences.put("key", "lorem ipsum"); 5 6 // read the value for your key. the second parameter is a fallback (optional otherwise throws) 7 final String value = appPreferences.getString("key", "default"); 8 Log.v(TAG, "value: " + value); // value: lorem ipsum 9 10 // read a key that isn't saved. returns the default (or throws without default) 11 final String defaultValue = appPreferences.getString("key2", "default"); 12 Log.v(TAG, "value: " + defaultValue); // value: default
(3).ContentProvider是Android官方支持的多进程安全的,参考:Android应用程序组件Content Provider应用实例
注意<1>:Messager只能串行处理消息,如果要处理大量的消息的话,还是用aidl
<2>:在AIDL文件中,并不是所有的数据类型都是可以使用的,AIDL只支持以下数据类型
(1).基本数据类型(int、long、char、boolean、double等)
(2).String和CharSequence
(3).List:只支持ArrayList,里面的每个元素都必须能够被AIDL支持
(4).Map:只支持HashMap,里面的每个元素都必须能够被AIDL支持,包括key和value
(5).Parcelable:所有实现了Parcelable接口的对象
(6).AIDL:所有的AIDL接口本身也可以在AIDL文件中使用