【Android学习】IPC(跨进程通信,Inter-Process Communication)

来源:互联网 发布:淘宝开直通车教程 编辑:程序博客网 时间:2024/06/04 19:09

1,概念

指两个进程之间进行数据交换的过程。

1)进程

2)线程

CPU调度的最小单元,是一种有限的系统资源。
Android主线程为UI线程。
如果主线程执行了很多耗时操作,会造成ANR(应用无响应,Application Not Responding)。

3)Binder

可以实现进程间通信。
Binder类实现了IBinder接口。

是一种虚拟的物理设备,设备驱动是/dev/binder。

从Android Framework角度:Binder是ServiceManager连接各种Manager和相应ManagerService的桥梁;
从Android应用层角度:Binder是客户端和服务端进行通信的媒介。如bindService,服务端会返回一个包含了服务端调用的Binder对象,客户端可以通过它获取服务端提供的服务或数据。

4)Socket

可以实现任意两个终端/进程的通信。

5)Serializable、Parcelable

6)AIDL(Android接口定义语言,Android Interface Definition Language)

Android系统中的进程之间不能共享内存,
Android通过AIDL来公开服务的接口,将这种可以跨进程访问的服务称为AIDL服务。

2,多进程模式

1)概念

默认进程的进程名为包名。
我们可以在eclipse的DDMS视图中查看进程信息。

2)实现

方法一:通过给四大组件指定Android:process属性,可以开启多进程模式。
方法二:通过JNI在native层去fork一个新的进程。

3)多进程问题

不同进程中的四大组件无法通过内存共享数据。

①静态成员和单例模式完全失效

Android为每一个进程分配了一个独立的虚拟机,不同的VM在内存上有不同的地址空间,导致不同的VM访问同一个类的对象会产生多份副本。

②线程同步机制完全失效

不同进程在不同内存中,锁对象(不是同一个对象)无法保证线程同步。

③SharedPreferences的可靠性下降

SharedPreferences不支持两个进程同时执行写操作,会丢失数据。

④Application会多次创建

在不同的VM上,会创建不同的Application。

3,跨进程通信

IPC方式的优缺点和适用场景

1)Intent传递数据

在Intent中附加extras来传递信息。

Activity、Service、Receiver都支持Intent中传递Bundle数据。
Bundle实现了Parcelable接口,可以在不同进程间传输。

Bundle中的数据必须能够被序列化:如基本类型、实现了Parcellable接口的对象、实现了Serializable接口的对象或者是Android支持的特殊对象。

2)ContentProvider

支持跨进程访问。共

3)享文件和SharedPreferences

适合用于数据同步要求不高的进程间通信,要妥善处理并发读/写的问题。

在面对高并发的读/写访问时,SharedPreferences有很大几率丢失数据,不建议用于跨进程通信。

4)基于Binder的Messenger

①Messenger

Messenger是轻量级的IPC方案,它的底层实现是AIDL。Messenger封装了AIDL,一次处理一个请求,不存在多线程并发的问题。
Messenger和Message实现了Parcelable接口。

Messenger载体:
what、arg1、arg2、Bundle、replyTo、object(只有系统定义的实现了Parcelable接口的对象才可以跨进程传递,自定义的实现了Parcelable接口的对象不可通过该字段传输)

②实现

用handler

③场景

Messenger以串行的方式处理客户端发来的消息,对于大量的并发请求需要一个个处理,效率低。

5)AIDL(Android Interface Description Language,Android接口描述语言)

①概念

Android 使用AIDL提供公开服务接口,使得不同进程间可以相互通信。
AIDL可以生成进程间的接口的代码,诸如service可能使用的接口。
在Service(服务)的onBind(Intent intent)方法中返回mBinder实现了aidl接口的对象

②场景

实现跨进程的方法调用。

③AIDL文件支持数据类型

使用这些类型时不需要import声明。

i>基本数据类型

ii>String和CharSequence

iii>List、Map、Parcelable

List:只支持ArrayList,里面每个元素都必须被AIDL支持。
Map:只支持HashMap,里面每个元素都必须被AIDL支持,包括key和value。
Parcelable:所有实现了Parcelable接口的对象。
AIDL:所有的AIDL接口本身也可以在AIDL文件中使用。
(这些类型内所包含的数据成员也只能是简单数据类型,String等其他支持类型)

④Binder连接池

创建一个Service即可完成多个AIDL接口的工作。

⑤建立AIDL服务

i>在Eclipse Android工程的Java包目录中建立一个扩展名为aidl的文件。该文件的语法类似于Java代码,但会稍有不同。
ii>如果aidl文件的内容是正确的,ADT会自动生成一个Java接口文件(*.java)。
iii>建立一个服务类(Service的子类)。
iv>实现由aidl文件生成的Java接口。
v>在AndroidManifest.xml文件中配置AIDL服务,尤其要注意的是,<action>标签中android:name的属性值就是客户端要引用该服务的ID,也就是Intent类的参数值。

⑥注意

i>aidl对应的接口名称必须与aidl文件名相同不然无法自动编译。
ii>aidl对应的接口的方法不能加访问权限修饰符,也不能用final,static。
iii>自定义类型和AIDL生成的其它接口类型在aidl描述文件中,应该显式import,即便在该类和定义的包在同一个包中。
iv>在aidl文件中所有非Java基本类型参数必须加上in、out、inout标记,以指明参数是输入参数、输出参数还是输入输出参数。
v>Java原始类型默认的标记为in,不能为其它标记。

6)Socket和网络通信

Socket分为流式套接字和用户数据报套接字。
注意:
A.不要在主线程访问网络(Android4.0以上设备会抛出异常:android.os.NetworkOnMainThreadException)
B.当Activity退出时,关闭当前Socket

阅读全文
0 0
原创粉丝点击