Android 应用内多进程实现

android平台支持多进程通信,也支持应用内实现多进程


1.那么多进程应该能为我们带来什么呢?

  我们都知道,android平台对应用都有内存限制,其实这个理解有点问题,应该是说android平台对每个进程有内存限制,比如某机型对对进程限制是24m,如果应用有两个进程,则该应该的总内存限制是2*24m。使用多进程就可以使得我们一个apk所使用的内存限制加大几倍。所以可以借此图片平台对应用的内存限制,比如一些要对图片、视频、大文件进程处理的好内存的应用可以考虑用多进程来解决应用操作不流畅问题。

2.实现多进程可以通过设置service、broadcast、activity的标签android:process来实现。


   一般情况下启动这些组件默认是在同一个进程里运行的,如果设置了android:process标签,则会运行在其他进程里。

  • 如果android:process的value不是":"开头,则系统里有同样名字的进程的话,会放到已存在的同名进程里运行,这样能减小消耗。
  • 如果android:process的value是以":"开头,则启动一个名字为value的进程。
例:
  1. <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.通常,一个应用的所有组件都运行在系统为这个应用所创建的默认进程中。这个默认进程是用这个应用的包名来命名的。

        标签的process属性可以设置成和所有组件都不同的默认值。但是这些组件可以通过设置自己的process值来覆写这个默认值,这样可以让你的应用跨多进程运行。

        如果被设置的进程名是以一个冒号开头的,则这个新的进程对于这个应用来说是私有的,当它被需要或者这个服务需要在新进程中运行的时候,这个新进程将会被创建。           如果这个进程的名字是以小写字符开头的(无冒号),则这个服务将运行在一个以这个名字命名的全局的进程中,当然前提是它有相应的权限。这将允许在不同应用中的各种组件可以共享一个进程,从而减少资源的占用

        例如一个应用运行在进程com.aoyousatuo.example中,android:process属性设置为com.rabbit.man,则新的进程名字为com.rabbit.run.


3.进程间通信有两种实现方式:

  1. 用系统框架实现
  2. 自己实现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.csdn.net/hudashi/article/details/7858125



关于进程的基础概念不再赘述

首先讨论如果一个程序内存在多个进程时创建顺序

看如下代码

[java]  view plain copy
  1. public class MyApplication extends Application{  
  2.   
  3.     public static int test = 0;  
  4.     @Override  
  5.     public void onCreate() {  
  6.         super.onCreate();  
  7.         Log.i("ydp""MyApplication onCreate pid:"+Process.myPid());  
  8.         startService(new Intent(this, ServiceA.class));  
  9.         startService(new Intent(this, ServiceB.class));  
  10.     }  
  11.       
  12. }  
MyApplication会在程序首次载入时运行onCreate方法,里面我开启了两个Service,

ServiceA在配置文件里标明了使用单独进程

[html]  view plain copy
  1. <service android:name=".ServiceA" android:process=":service"></service>  

大家是不是觉得步骤是这样,

MyApplication onCreate--->ServiceA onStart 并创建新进程 ---->ServiceB onStart 保持原进程

现实比想像严峻的多啊,先看看LOG输出

[html]  view plain copy
  1. MyApplication onCreate pid:26660  
  2. MyApplication onCreate pid:26673  
  3. Service A onStart pid:26673  
  4. Service A onStart pid:26673  
  5. Service B onStart pid:26660  
  6. Service B onStart pid:26660  

不难看出,实际实际情况是首先创建一个PID为26660的Application,在遇到startServiceA时,由于ServiceA采用了新的进程,则 先要初始化该进程 ,所以又创建了一个PID为26673的Application实例,新进程实例出来,26660进程的startServiceA才得以继续,由于此时已经存在两个进程,两个独立的虚拟机,所以我们看到26673进程也执行了startServiceA, 此时由于新进程已存在,所以不再重新创建 ,最后两个进程有 互不干扰 的执行了startServiceB


事实是android在遇到需要放在新进程的组件时,首先创建此进程,此时当前进程的当前线程是阻塞的,直到新进程创建。


所以当我们要启动单独进程组件时需要注意,进程的创建会影响继承了Application的实例,里面的方法会完全再执行一遍,很多认喜欢把大量初始化工作放在里面,尽管进程由于处于不同虚拟机,里面的所有内存私有,但一些影响文件、UI等无进程概念的问题会出现。


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值