andorid 进程通信机制

来源:互联网 发布:淘宝男士银项链 编辑:程序博客网 时间:2024/06/14 18:31

Android中的IPC机制

Android IPC简介

IPC是Inter-Process Communication的缩写,含义就是进程间通信或者跨进程通信,是指两个进程之间进行数据交换的过程。那么什么是进程,什么是线程,进程和线程是两个截然不同的概念。在操作系统中,线程是CPU调度的最小单元,同时线程是一种有限的系统资源。而进程指的一个执行单元,在PC和移动设备上指的是一个程序或者一个应用。一个进程可以包含多个线程,因此进程和线程是包含被包含的关系,最简单情况下,一个进程可以只有一个线程,即主线程,在Android里面也叫UI线程,在UI线程里才能操作界面元素。

那么在Android中,有特色的进程间通信方式就是Binder了,通过Binder可以轻松实现进程间通信。除了Binder,Android还支持Socket,通过Socket也可以实现任意两个终端之间的通信,当然一个设备上的两个进程之间通过Socket通信自然也是可以的。

说到IPC的使用场景就必须提到多进程,只有面对多进程这种场景下,才需要考虑进程间通信。所有运行在不同进程中的四大组件,只要它们之间需要通过内存来共享数据,都会共享失败,这也是多进程所带来的主要影响。正常情况下,四大组件中间不可能不通过一些中间层来共享数据,那么通过简单地指定进程名来开启多进程都会无法正确运行。一般来说,使用多进程会造成如下几方面的问题:

  • 静态成员和单例模式完全失效
  • 线程同步机制完全失效
  • SharedPreferences的可靠性下降
  • Application会多次创建

为了解决这个问题,系统提供了很多跨进程通信方法,虽然说不能直接地共享内存,但是通过跨进程通信我们还是可以实现数据交互。实现跨进程通信的方式有很多,比如通过Intent来传递数据,共享文件SharedPreference,基于Binder的Messenger和AIDL以及Socket等。

IPC基础概念介绍

Serializable接口

Serializable是Java提供的一个序列化接口,它是一个空接口,为对象标准的序列化和反序列化操作。使用Serializable来实现序列化相当简单,一句话即可。

public class User implements Serializable {  private static final long seriaVersionUID = 519067123721295773L}

Parcelable接口

Parcel内部包装了可序列化的数据,可以在Binder中自由传输,在序列化过程中需要实现的功能有序列化、反序列化和内容描述序列化功能有writeToParcel方法来完成,最终是通过Parcel中的一系列write方法来完成的。用法如下:

public class MyParcelable implements Parcelable {    // You can include parcel data types    private int mData;    private String mName;        // We can also include child Parcelable objects. Assume MySubParcel is such a Parcelable:    private MySubParcelable mInfo;    // This is where you write the values you want to save to the `Parcel`.      // The `Parcel` class has methods defined to help you save all of your values.      // Note that there are only methods defined for simple values, lists, and other Parcelable objects.      // You may need to make several classes Parcelable to send the data you want.    @Override    public void writeToParcel(Parcel out, int flags) {        out.writeInt(mData);        out.writeString(mName);        out.writeParcelable(mInfo, flags);    }    // Using the `in` variable, we can retrieve the values that     // we originally wrote into the `Parcel`.  This constructor is usually     // private so that only the `CREATOR` field can access.    private MyParcelable(Parcel in) {        mData = in.readInt();        mName = in.readString();        mInfo = in.readParcelable(MySubParcelable.class.getClassLoader());    }    public MyParcelable() {        // Normal actions performed by class, since this is still a normal object!    }    // In the vast majority of cases you can simply return 0 for this.      // There are cases where you need to use the constant `CONTENTS_FILE_DESCRIPTOR`    // But this is out of scope of this tutorial    @Override    public int describeContents() {        return 0;    }    // After implementing the `Parcelable` interface, we need to create the     // `Parcelable.Creator<MyParcelable> CREATOR` constant for our class;     // Notice how it has our class specified as its type.      public static final Parcelable.Creator<MyParcelable> CREATOR            = new Parcelable.Creator<MyParcelable>() {        // This simply calls our new constructor (typically private) and         // passes along the unmarshalled `Parcel`, and then returns the new object!        @Override        public MyParcelable createFromParcel(Parcel in) {            return new MyParcelable(in);        }        // We just need to copy this and change the type to match our class.        @Override        public MyParcelable[] newArray(int size) {            return new MyParcelable[size];        }    };}

Serializable和Parcelable区别

Serializable是Java中的序列化接口,其使用起来简单但是开销很大,在序列化和反序列化过程中需要大量的I/O操作。而Parcelable是Android中的序列化方式,因此更适合用在Android平台上,它的缺点就是使用起来稍微麻烦点,但是它的效率很高。

Binder
直观来说,Binder是Android中的一个类,它实现了IBinder接口。从IPC角度来说,Binder是Android中的一种跨进程通信方式,Binder还可以理解为一种虚拟的物理设备,它的设备驱动是/dev/binder,该通信方式在Linux中没有。从Android Framework角度来说,Binder是ServiceManager连接各种Manager(ActivityManager、WindowManager等等)和相应ManagerService的桥梁。从Android应用层来说,Binder是客户端和服务端进行通信的媒介,当bindService的时候,服务端会返回一个包含了服务端业务调用的Binder对象,通过Binder对象,客户端就可以获取服务端提供的服务或者数据,这里的服务包括普通服务和基于AIDL的服务。

Binder工作机制

Android中的IPC方式

使用Bundler

我们知道,四大组件中三大组件(activity、service、receiver)都是支持在Intent中传递Bundle数据的,由于Bundle实现了Parcelable接口,所以它可以方便地在不同的进程间传输。

使用文件共享

共享文件也是一种不错的进程间通信方式,两个进程间通过读/写同一个文件来交换数据,比如A进程把数据写入文件,B进程通过读取这个文件来获取数据。

使用Messenger

Messenger可以翻译为信使,顾名思义,通过它可以在不同进程中传递Message对象,在Message中放入我们需要传递的数据,就可以轻松地实现数据的进程间传递。Messenger是一种轻量级的IPC方案,它的底层实现是AIDL,实现Messenger有以下两个步骤,分为服务端进程和客户端进程。

Messenger工作原理

使用AIDL

远程服务跨进程通信的一种方式。

使用ContentProvider

ContentProvider是Android中提供的专门用于不同应用间进行数据共享的方式,它的底层实现同样也是Binder。

使用Socket

Socket也称为“套接字”,是网络通信中的概念,它分为流式套接字和用户数据套接字两种,分别应于网络的传输控制层中的TCP和UDP协议。

选用合适的IPC方式

不同IPC方式比较

转载出处:特立独行Allen   http://www.cnblogs.com/cr330326/p/6340958.html 

原创粉丝点击