android进程间通信的选择

前言:

这一段时间正在研究android中多进程相关的使用,之前也写过一篇关于对AIDL的一些理解AIDL简介,今天突然心血来潮,打算整理一下在不同情况下,对进程间通信方式的选择。

概要:

本文主要是分析不同情况下对通信方式的选择,并会简单说明利弊原因,会涉及到AIDL,Meeanger,BInder,Intent,四大组件等相关的知识,基础原理请自行补充学习,本文不做太多介绍。

正文:

众所周知,Android中一个应用对应只有一个进程,这个进程的名称就是应用程序的包名,进程是系统分配资源和调度的最小单位,每个进程都有自己独立的资源和内存空间,其他进程是不能随意的访问当前进程的资源和内存的。

系统给每个进程分配的内存大小都是有限制的,一旦这个进程占用的内存超过了这个限制,就会出现OOM的错误。如果程序需要频繁处理大的图片或者需要读取很多的数据到内存中使用的时候等,系统分配给当前进程的内存就不能满足我们的需要,如果添加一些人为的GC处理会影响到程序运行的流畅性,而且有时候可能效果不明显。有时候在sdk>=11的时候,我们可以在AndroidManifest.xml文件的application标签中添加"android:largeHeap="true""这句话来向系统申请使用更多的内存,但这种方法存在弊端,比如在sdk<11的时候或者申请了更多内存还是不能满足需要的时候就没什么用,而且如果很多程序都请内存的话,会影响整个系统的运行效率。

为了彻底解决这个问题,引入了多进程的概念,允许在同一个应用内,为了分担主进程的压力,将应用中需要内存大的页面等单独开进程。那么进程间通信得到方式就很重要了。

一,进程间通信必要性:

1)实现进程间通信,可以让进程间或应用间的资源实现共享。

2)一个应用对应多进程,分担内存,避免OOM错误。

二,进程间通信的方式以及利弊:

android sdk提供了四种进程间通讯的方式,分别对应了android的四大组件。

1)Activity跨进程调用其他应用的Activity;

2)Content Provider可以跨进程访问其他应用程序中的数据,并且可以对其进行增,删,改的操作;

3)BroadCast可以向系统中所有的应用程序发送广播,需要跨进程通讯的应用都可以监听这些广播;

4)Service返回的是java对象,基于AIDL机制进行进程间通讯。

下面我们针对以上的几种方式进行一些说明,分析一下使用过程中的优劣。

1)Activity

Activity进程间访问和进程内访问稍有不同,虽然都依赖Intent对象来实现,但是进程内访问只需要通过指定Context和Activity的Class对象就可以实现,而跨进程通讯只需要指定action,有时还需要指定Uri来实现。例如调拨号功能的代码:

Intent intent = new Intent(Intent.ACTION_CALL, Uri.parse("tel:110"));
startActivity(intent);


这种方式的前提是,这个Activity必须是共享的,并且注册了action。需要通过指定Uri或者Intent来实现数据的传递,而且要调用startActivity,startActivityForResult)等方法,不能持续通信。

2)Content Provider

应用程序可以使用SqlLite或者文件来存储数据,Content Provider实现了应用程序间数据共享,允许其他应用程序对数据进行增,删,查,改。Android系统本身提供了很多的Content Provider,比如音频,视屏,通讯录等,我们可以通过Content Provider获得这些信息,这些列表数据将会以Cursor对象返回。从Content Provider返回的数据是二维表的形式。

这种方式主要是实现本地持久化数据的通信。

3)BroadCast

这是一种被动的进程间通讯机制,当广播向系统发送通知的时候,其他应用程序只能被动地接受广播数据,不能主动进行沟通。如果需要主动发送广播,需要配合Intent来发送数据。

这种方式适合一对多,而且性能比较差,如果系统中广播比较多的话会出现延迟,甚至有可能发送失败。

4)Service

Service是利用AIDL机制进行进程间通信的。如果是Service和应用在同一个进程中调用的时候需要手动开线程来执行耗时任务。要实现进程间通信,我们需要借助AIDL来实现,通过bindService,实现持续通信,这种方式用的较多。这里我们要介绍的有两种方式,一种是AIDL,另一种是在AIDL基础上封装的Messanger。

AIDL和Messanger的区别:

a,Messenger是在AIDL基础上进行了封装,不用写aidl文件,从代码角度讲,这种方法相对简单点,因为本质上还是AIDL,所以执行效率上应该没有太大差异。

b,从service端来看,AIDL对client的请求是多线程处理的,Messenger是单线程处理的。AIDL使用的时候,在收到一个请求的时候,就启动一个线程去执行相应的操作;而Messenger在收到一个请求时,会添加到Handler的MessageQueue里面,Handler是需要绑定一个线程,然后不断地poll message执行相关的操作,这个过程是同步的。

c,AIDL你可以自己定义相应的方法,并且指定返回值。而Messenger只提供了send方法,发送一个Message对象,没有返回值,需要调用Message的replyTo传递返回值过去。

需要注意的是Messenger是单线程的,线程安全的,一般非多线程的进程间通信我们采用这种方式就可以了;而AIDL是多线程,非线程安全的,只有在多线程处理的情况下使用这种方式,还要对线程加安全锁。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值