收藏 分享(赏)

android进程间通讯.ppt

上传人:hyngb9260 文档编号:7268862 上传时间:2019-05-12 格式:PPT 页数:23 大小:487KB
下载 相关 举报
android进程间通讯.ppt_第1页
第1页 / 共23页
android进程间通讯.ppt_第2页
第2页 / 共23页
android进程间通讯.ppt_第3页
第3页 / 共23页
android进程间通讯.ppt_第4页
第4页 / 共23页
android进程间通讯.ppt_第5页
第5页 / 共23页
点击查看更多>>
资源描述

1、Android进程间通讯,目录,Binder框架Binder介绍Android跨进程通讯 ActivityContent ProviderBroadcastAIDL,Binder 框架(一),Binder 框架(二),Binder 应用层类继承关系,Android系统通信方式 Binder,Binder通信的实现 : 1.Binder通信是通过linux的binder driver来实现的, 2.Binder通信操作类似线程迁移(thread migration),两个进程间IPC看起来就象是一个进程进入另一个进程执行代码然后带着执行的结果返回; 3.Binder的用户空间为每一个进程维护着一

2、个可用的线程池,线程池用于处理到来的IPC以及执行进程本地消息,Binder通信是同步而不是异步。,Binder,Android中的 Binder通信实现要点: 1. Android中的Binder通信是基于Service与Client的工作模型的; 2. 所有需要IBinder通信的进程都必须创建一个IBinder接口; 3. 系统中有一个进程管理所有的system service: 4. Android不允许用户添加非授权的System service; 5. 现在源码开放了,我们可以修改一些代码来实现添加底层system Service的目的; 6. 对用户程序来说,我们也要创建serv

3、er,或者Service用于进程间通信; 7. ActivityManagerService管理JAVA应用层所有的service创建与连接(connect),disconnect; 8. 所有的Activity也是通过这个service来启动,加载的; 9. ActivityManagerService也是加载在Systems Servcie中的;,Binder,Android的 Service工作流程 1.Android虚拟机启动之前系统会先启动service Manager进程; 2.service Manager打开binder驱动,并通知binder kernel驱动程序这个进程将作

4、为System Service Manager; 3.然后该进程将进入一个循环,等待处理来自其他进程的数据。 4.用户创建一个System service后,通过defaultServiceManager得到一个远程ServiceManager的接口,通过这个接口我们可以调用addService函数将System service添加到Service Manager进程中; 5.然后client可以通过getService获取到需要连接的目的Service的IBinder对象,这个IBinder是Service的BBinder在binder kernel的一个参考, 6.所以service IB

5、inder 在binder kernel中不会存在相同的两个IBinder对象,每一个Client进程同样需要打开Binder驱动程序。对用户程序而言,我们获得这个对象就可以通过binder kernel访问service对象中的方法。 7.Client与Service在不同的进程中,通过这种方式实现了类似线程间的迁移的通信方式,对用户程序而言当调用Service返回的IBinder接口后,访问Service中的方法就如同调用自己的函数。,binder,进程有自己的地址空间,不同进程间的通信并不能直接引用地址。一般的解决途径是,发送进程把需要传送的数据按照一定格式(marshall)转换成二进

6、制形式/特定格式的数据,发往接收进程;接收进程收到二进制形式、特定格式的数据后,反转换(unmarshall)成原文数据,然后使用。binder使用的就是这种步骤。 binder使用的是同步c/s模型,s循环阻塞在接收数据操作上,随时处理c的数据,处理后发送回c;c则将请求服务的数据发送到s,阻塞在收取s返回数据,收到数据后,继续自己的工作。 binder的框架可以分成3层 最下层是linux os和binder driver。binder driver本质上是进程间的共享内存,各进程将要发送到其它进程的数据写入到driver,从driver读取其它进程发送来的数据。 中间层是cpp实现的fr

7、amework,完成数据的接收发送转换,和c/s流程的支持。 其实到中间层,binder的架构就已经完全具备了。但android使用的是java做为一般app的开发语言。所以还需要jni和相应java binder类的支持,这就是中间层上面的第三层:jni/java,binder driver,binder driver是binder机制的基础,是实现ipc的通道。 binder driver与framework和app的功能操作是用ioctl方式实现的。最基本的操作是数据读写操作。一次读写操作有两个子操作组成:写子操作和读子操作。driver为每个进程和线程维护了一个数据结构,其中有一个li

8、st,挂接了其它进程写入的数据,还有一个信号量。写子操作负责将数据挂接到接收进程对应数据结构的list上。读子操作负责处理自己进程中list上的数据,传回framework和app。 binder driver的第二个功能是为了支持rpc,就是维护本地函数和远端proxy的handle之间的对应关系。更复杂的是维护两个远端Proxy的handle之间的对应关系,这两个proxy是同一rpc的proxy。,binder framework,binder的framework是cpp实现的,这里分成本地local/s和远端remote/c两半来描述。 公共类IBinder派生出两个子类,BBinde

9、r用于local,BpBinder用于remote。 本地实现的类以BBinder为基类派生,接收数据后,处理,并将结构发会远端。 远端proxy的类使用BpBinder,接收和发送数据到本地。 进一步方便开发,引入了IInterface类,开发者从Interface派生子类,定义自己需要的rpc操作。 在IInterface的装饰下,从BBinder派生出了本地的关键类 BnInterface;从BpRefBase派生出了包含成员BpBinder对象的远端关键类BpInterface。 于是,创世纪中,神说:要有光,就有了光。神看光是好的,就把光暗分开了。 神称光为昼,称暗为夜。有晚上,有早

10、晨,这是头一日。,binder jni,java类和aidl工具,binder framework的机制要被java使用,需要经过包装。除了jni相关部分,android在java中还定义了几个相关的接口和类,IBinder,Binder,BinderProxy,IInterface,BinderInternal。 aidl工具则是方便java实现c/s结构的一个工具,开发者编写简单的接口描述idl文件,则aidl自动生成local和remote的Binder类。让开发者关注在实际的功能开发上,不必为binder机制耗费无谓的精力,parcel,为了便于ipc之间传递的数据的操作,binder

11、引入了parcel的概念。parcel可以想成快递公司的包装箱,需要传递的各种类型的数据都被打包进parcel类,binder负责传递parcel对象,接收端则从parcel解出数据。这样的机制即减少了各种数据类型对传递的复杂性,又可以通过增加打包/解包parcel的数据类型,轻易实现扩展。 parcel已经支持容纳基本数据类型和一些复合数据类型。 在framework层面,parcel提供了Flattenable基类,可以扩展parcel容纳的数据类型。 在java parcel层面,parcel提供了Parcelable接口,可以扩展parcel容纳的数据类型。,依赖于binder的ser

12、vice,ipc/rpc已经被binder机制解决掉了,那么service面临的唯一问题就是service如何让想使用service的client招到service。解决的方案就是 service manager。service manager是一个特殊进程,每个service都会注册登记到service manager中,而client可以从service manager查询得到自己需要使用的service。,Android跨进程通讯,在android SDK中提供了4种用于跨进程通讯的方式。这4种方式正好对应于android系统中4种应用程序组件: Activity、 Content Pr

13、ovider、 Broadcast Service。其中Activity可以跨进程调用其他应用程序的Activity;Content Provider可以跨进程访问其他应用程序中的数据(以Cursor对象形式返回),当然,也可以对其他应用程序的数据进行增、删、改操 作;Broadcast可以向android系统中所有应用程序发送广播,而需要跨进程通讯的应用程序可以监听这些广播;Service和Content Provider类似,也可以访问其他应用程序中的数据,但不同的是,Content Provider返回的是Cursor对象,而Service返回的是Java对象,这种可以跨进程通讯的服务叫

14、AIDL服务,访问其他应用程序的Activity,Activity既可以在进程内(同一个应用程序)访问,也可以跨进程访问。Activity的跨进程访问与进程内访问略有不同。虽然它们都需要Intent对象,但跨进程访问并不需要指定Context对象和Activity的 Class对象,而需要指定的是要访问的Activity所对应的Action(一个字符串)。有些Activity还需要指定一个Uri(通过 Intent构造方法的第2个参数指定)。如果想在同一个应用程序中访问Activity,需要指定Context对象和Activity的Class对象。 Intent intent = new In

15、tent(this , Test.class ); startActivity(intent); Activity的跨进程访问与进程内访问略有不同。虽然它们都需要Intent对象,但跨进程访问并不需要指定Context对象和Activity的 Class对象,而需要指定的是要访问的Activity所对应的Action(一个字符串)。有些Activity还需要指定一个Uri(通过 Intent构造方法的第2个参数指定)。,Activity共享,1. 在AndroidManifest.xml文件中指定Action。指定Action要使用标签,并在该标签的android:name属性中指定Actio

16、n 2. 在AndroidManifest.xml文件中指定访问协议。在指定Uri(Intent类的第2个参数)时需要访问协议。访问协议需要使 用标签的android:scheme属性来指定。如果该属性的值是“abc”,那么Uri就应该是“abc:/Uri的主体 部分”,也就是说,访问协议是Uri的开头部分。 3. 通过getIntent().getData().getHost()方法获得协议后的Uri的主体部分。这个Host只是个称谓,并不一定是主机名。读者可以将其看成是任意的字符串。 4. 从Bundle对象中获得其他应用程序传递过来的数据。 5. 这一步当然是获得数据后做进一步的处理了。

17、至于如何处理这些数据,就得根据具体的需求决定了。,Content Provider,Android应用程序可以使用文件或SqlLite数据库来存储数据。Content Provider提供了一种在多个应用程序之间数据共享的方式(跨进程共享数据)。应用程序可以利用Content Provider完成下面的工作 1. 查询数据 2. 修改数据 3. 添加数据 4. 删除数据 虽然Content Provider也可以在同一个应用程序中被访问,但这么做并没有什么意义。Content Provider存在的目的向其他应用程序共享数据和允许其他应用程序对数据进行增、删、改操作。 Android系统本身提

18、供了很多Content Provider,例如,音频、视频、联系人信息等等。我们可以通过这些Content Provider获得相关信息的列表。这些列表数据将以Cursor对象返回。因此,从Content Provider返回的数据是二维表的形式。,对于访问Content Provider的程序,需要使用ContentResolver对象。该对象需要使用getContentResolver方法获得,代码如下: ContentResolver cr = getContentResolver(); 与Activity一样,Content Provider也需要与一个URI对应。每一个Content

19、 Provider可以控制多个数据集,在这种情况下,每一个数据集会对应一个单独的URI。所有的URI必须以“content:/”开头。 为了程序更容易维护,也为了简化程序代码,一般将URI定义成一个常量,编写Content Provider的具体步骤,1. 编写一个继承于android.content.ContentProvider的子类。该类是ContentProvider的核心类。在该类中会实现 query、insert、update及delete方法。实际上调用ContentResolver类的这4个方法就是调用 ContentProvider类中与之要对应的方法。在本文中只介绍quer

20、y。至于insert、update、delete和query的用法类 似。也是通过Uri传递参数,然后在这些方法中接收这些参数,并做进一步地处理。 2. 在AndroidManifest.xml文件中配置ContentProvider。要想唯一确定一个ContentProvider,需要指定这个 ContentProvider的URI,除此之外,还需要指定URI所对应的ContentProvider类。这有些象Servlet的定义,除了要 指定Servlet对应的Web地址,还要指定这个地址所对应的Servlet类。,广播(Broadcast),广播是一种被动跨进程通讯的方式。当某个程序向系统

21、发送广播时,其他的应用程序只能被动地接收广播数据。这就象电台进行广播一样,听众只能被动地收听,而不能主动与电台进行沟通。 在应用程序中发送广播比较简单。只需要调用sendBroadcast方法即可。该方法需要一个Intent对象。通过Intent对象可以发送需要广播的数据。 先建一个android工程:sendbroadcast。在XML布局文件中放两个组件:EditText和Button,当单击按钮后,会弹出显示 EditText组件中文本的对话框,关闭对话框后, 会使用sendBroadcast方法发送消息,并将EditText组件的文本通过Intent对象发送出去。,AIDL服务,服务(

22、Service)是android系统中非常重要的组件。Service可以脱离应用程序运行。也就是说,应用程序只起到一个启动Service的作用。一但Service被启动,就算应用程序关闭,Service仍然会在后台运行。 android系统中的Service主要有两个作用:后台运行和跨进程通讯。后台运行就不用说了,当Service启动后,就可以在Service对象中 运行相应的业务代码,而这一切用户并不会察觉。而跨进程通讯是这一节的主题。如果想让应用程序可以跨进程通讯,就要使用我们这节讲的AIDL服 务,AIDL的全称是Android Interface Definition Language

23、,也就是说,AIDL实际上是一种接口定义语言。通过这种语言定义接口后,Eclipse插件(ODT)会自动生成相应的Java代码接 口代码。,编写AIDL步骤,1. 在Eclipse工程的package目录中建立一个扩展名为aidl的文件。package目录就是Java类所在的目录。该文件的语法类似于Java代码。aidl文件中定义的是AIDL服务的接口。这个接口需要在调用AIDL服务的程序中访问。 2. 如果aidl文件的内容是正确的,Eclipse插件会自动生成一个Java接口文件(*.java)。 3. 建立一个服务类(Service的子类)。 4. 实现由aidl文件生成的Java接口。 5. 在AndroidManifest.xml文件中配置AIDL服务,尤其要注意的是,标签的android:name属性值就是客户端要引用该服务的ID,也就是Intent类构造方法的参数值。,

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 企业管理 > 管理学资料

本站链接:文库   一言   我酷   合作


客服QQ:2549714901微博号:道客多多官方知乎号:道客多多

经营许可证编号: 粤ICP备2021046453号世界地图

道客多多©版权所有2020-2025营业执照举报