IPC机制

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了IPC机制相关的知识,希望对你有一定的参考价值。

开启多进程和负面影响
IPC:进程间通讯。
线程与进程是包含的关系。

使用只有1个方法:给四大组件在manifest里指定android:process属性,无法给一个线程或者实体类指定其运行时所在的进程。
  1. android:process=":remote"
进程名以":"开头的进程属于私有进程,其他应用的组件不可以和它跑早同一个进程中,而进程名不以":"开头的属于全局进程,
其他应用可以通过ShareUID方式可以和它跑在同一个进程中。

UID:每个应用分配唯一的UID,两个相同UID签名相同可以共享数据。

多线程的负面影响:
1、静态成员和单例模式完全失效(通过内存来共享数据都会失败);
2、线程同步机制完全失效;
3、SharedPreferences可靠性下降(内存中只有一份SharedPreferences);
4、Application会多次创建;
结论:多进程模式中,不同进程的组件会拥有独立的虚拟机、Application以及内存空间。

IPC基础
Serializable:
Java提供的序列化接口
用的时候用类实现Serializable并在接口里面声明
  1. private static final long serialVersionUID = 51989342343L;
对象的序列化和反序列化使用ObjectOutputStream和ObjectInputStream。手动指定serialVersionUID可以很大程度避免反序列化失败。

Parcelable:
Android提供推荐的新的序列化接口,效率高。
  1. public class User implements Parcelable, Serializable {
  2. private static final long serialVersionUID = 519067123721295773L;
  3. public int userId;
  4. public String userName;
  5. public boolean isMale;
  6. public Book book;
  7. public User() {
  8. }
  9. public User(int userId, String userName, boolean isMale) {
  10. this.userId = userId;
  11. this.userName = userName;
  12. this.isMale = isMale;
  13. }
  14. //返回当前对象的内容描述
  15. public int describeContents() {
  16. return 0;
  17. }

  18. //序列化
  19. public void writeToParcel(Parcel out, int flags) {
  20. out.writeInt(userId);
  21. out.writeString(userName);
  22. out.writeInt(isMale ? 1 : 0);
  23. out.writeParcelable(book, 0);
  24. }
  25. public static final Parcelable.Creator<User> CREATOR = new Parcelable.Creator<User>() {
  26. //从系列化后的对象中创建原始对象
  27. public User createFromParcel(Parcel in) {
  28. return new User(in);
  29. }
  30. //创建指定长度的原始对象数组
  31. public User[] newArray(int size) {
  32. return new User[size];
  33. }
  34. };

  35. //反序列化
  36. private User(Parcel in) {
  37. userId = in.readInt();
  38. userName = in.readString();
  39. isMale = in.readInt() == 1;
  40. book = in.readParcelable(Thread.currentThread().getContextClassLoader());
  41. }
  42. @Override
  43. public String toString() {
  44. return String.format(
  45. "User:{userId:%s, userName:%s, isMale:%s}, with child:{%s}",
  46. userId, userName, isMale, book);
  47. }
  48. }

Binder:
IPC角度:Android中的一种跨进程通讯方式;
Android Framework角度:ServiceManager连接各种Manager和相应ManagerService的桥梁;
Android应用层:客户端和服务端进行通讯的媒介,当bindService的时候,服务端会返回一个包含了服务端业务调用的Binder对象,通过这个Binder对象,客户端可以
                            获取服务端的数据和服务(包含普通服务和基于AIDL服务)。

实现了IBinder接口,在android开发中主要用在Service中,包括AIDL和Messenger,普通servece中Binder不涉及进程间通讯,Messenger底层是AIDL。
AIDL的本质是系统为我们提供了一种快速实现Binder的工具。
Binder的两个重要方法linkToDeath和unlinkToDeath,当Binder死亡时会收到通知。
技术分享

IPC实现方式
Intent中附加extra(传递Bundle数据),ContentProvider、文件SD卡共享(适合在对数据同步要求不高的进程之间进行通讯)、Binder、网络通讯(Socket)、AIDL

Messenger:数据传输必须将数据放入Message中,Messenger和Message都实现了Parcelable接口,串行处理。
AIDL:Android使用一种接口定义语言(Interface Definition Language,IDL)来公开服务的接口。 
           AIDL中会大量使用到Parcelable来序列化对象。
           如果AIDL中用到了自定义的Parcelable对象,必须建立个和他同名的AIDL文件。
           AIDL流程:创建一个Service和一个AIDL接口,接着创建一个类继承自AIDL接口中的Stub类并实现Stub中的抽象方法,在Service的onBind方法中返回这个类的
                              对象,然后客户端就可以绑定服务端Service,建立连接后就可以访问远程服务端的方法。

Socket:不仅可以实现进程间通讯,还可以实现设备间通讯,前提是设备之间的IP可见;
ContentProvider:天生适合进程间通讯,底层Binder
技术分享

Binder连接池
BinderPool:将每个业务模块的Binder请求统一转发到远程Service中去执行;
能够极大提高AIDL的开发效率,并可避免大量Service的创建。
技术分享





























以上是关于IPC机制的主要内容,如果未能解决你的问题,请参考以下文章

Android系统进程间通信(IPC)机制Binder中的Server启动过程源代码分析

Android AIDL使用详解_Android IPC 机制详解

序列化作为 IPC 机制?

Android——IPC机制IPC概念以及Binder机制

C程序IPC消息

C 中的共享内存代码片段