android平台支持多进程通信,也支持应用内实现多进程
1.那么多进程应该能为我们带来什么呢?
我们都知道,android平台对应用都有内存限制,其实这个理解有点问题,应该是说android平台对每个进程有内存限制,比如某机型对对进程限制是24m,如果应用有两个进程,则该应该的总内存限制是2*24m。使用多进程就可以使得我们一个apk所使用的内存限制加大几倍。所以可以借此图片平台对应用的内存限制,比如一些要对图片、视频、大文件进程处理的好内存的应用可以考虑用多进程来解决应用操作不流畅问题。
2.实现多进程可以通过设置service、broadcast、activity的标签android:process来实现。
一般情况下启动这些组件默认是在同一个进程里运行的,如果设置了android:process标签,则会运行在其他进程里。
- 如果android:process的value不是":"开头,则系统里有同样名字的进程的话,会放到已存在的同名进程里运行,这样能减小消耗。
- 如果android:process的value是以":"开头,则启动一个名字为value的进程。
- <service android:name=".ServiceA" android:process=":service"></service>
实现应用多进程之后,就是进程间通信啦
见:http://blog.sina.com.cn/s/blog_4c0706560101ncz4.html
注:
1.冒号’:’这个前缀将把这个名字附加到你的包所运行的标准进程名字的后面作为新的进程名称。
例如:一个应用的包名为com.aoyousatuo.example, 则本例中服务将运行的新进程的名称为com.aoyousatuo.example:service.(注意,如果声明文件中的组件或者应用没有指定这个属性则默认应用和其组件将相应运行在以其包名命名的进程中).
android:process服务所在进程的名字。
2.通常,一个应用的所有组件都运行在系统为这个应用所创建的默认进程中。这个默认进程是用这个应用的包名来命名的。
3.进程间通信有两种实现方式:
- 用系统框架实现
- 自己实现AIDL
系统框架实现进程通信有用过Service,Broadcast,Activity,ContentProvider
转自:http://www.eoeandroid.com/thread-320076-1-1.html
Android中,默认一个APK包就对应一个进程,其进程名就为AndroidManifest.xml文件中 指定的package名。我们可以通过Activity, Service, BroadCastReceiver, ContentProvider的android:process属性来实现单APK多进程,但是需要注意进程间内存的不可见性。
举例见:http://blog.youkuaiyun.com/hudashi/article/details/7858125
关于进程的基础概念不再赘述
首先讨论如果一个程序内存在多个进程时创建顺序
看如下代码
- public class MyApplication extends Application{
- public static int test = 0;
- @Override
- public void onCreate() {
- super.onCreate();
- Log.i("ydp", "MyApplication onCreate pid:"+Process.myPid());
- startService(new Intent(this, ServiceA.class));
- startService(new Intent(this, ServiceB.class));
- }
- }
ServiceA在配置文件里标明了使用单独进程
- <service android:name=".ServiceA" android:process=":service"></service>
大家是不是觉得步骤是这样,
MyApplication onCreate--->ServiceA onStart 并创建新进程 ---->ServiceB onStart 保持原进程
现实比想像严峻的多啊,先看看LOG输出
- MyApplication onCreate pid:26660
- MyApplication onCreate pid:26673
- Service A onStart pid:26673
- Service A onStart pid:26673
- Service B onStart pid:26660
- Service B onStart pid:26660
不难看出,实际实际情况是首先创建一个PID为26660的Application,在遇到startServiceA时,由于ServiceA采用了新的进程,则 先要初始化该进程 ,所以又创建了一个PID为26673的Application实例,新进程实例出来,26660进程的startServiceA才得以继续,由于此时已经存在两个进程,两个独立的虚拟机,所以我们看到26673进程也执行了startServiceA, 此时由于新进程已存在,所以不再重新创建 ,最后两个进程有 互不干扰 的执行了startServiceB
事实是android在遇到需要放在新进程的组件时,首先创建此进程,此时当前进程的当前线程是阻塞的,直到新进程创建。
所以当我们要启动单独进程组件时需要注意,进程的创建会影响继承了Application的实例,里面的方法会完全再执行一遍,很多认喜欢把大量初始化工作放在里面,尽管进程由于处于不同虚拟机,里面的所有内存私有,但一些影响文件、UI等无进程概念的问题会出现。