Android9_IPC机制之基础概念介绍(序列化和Binder)

===========【对象序列化】==========================
Parcelable接口与Serializable接口:

Parcelable和Serializable接口的用法和区别:https://www.cnblogs.com/jiefeiduan/p/3959411.html

Parcelable的作用:https://www.jianshu.com/p/32a2ec8f35ae

安卓中Parcelable的原理与使用方法:https://www.jianshu.com/p/df35baa91541

Android Parcelable 接口用法小结:https://www.jianshu.com/p/84f833fb3fb5

安卓如何使用parcelable接口:https://blog.csdn.net/bzlj2912009596/article/details/81091919

Android中Parcelable的使用:https://www.cnblogs.com/tangZH/p/10998065.html

Android Parcel对象详解:https://blog.csdn.net/rainbowchou/article/details/54294394

===============【Binder机制】=======================

(这个讲得不错)3分钟带你看懂android中的Binder机制: https://segmentfault.com/a/1190000018317841?utm_source=tag-newest#articleHeader1

(知乎上,目前来看讲得最好)Binder机制:https://zhuanlan.zhihu.com/p/35519585

安卓Binder机制:https://www.jianshu.com/p/225ccd39a667

Android跨进程通信:https://www.jianshu.com/p/375e3873b1f4

理解binder机制:https://www.jianshu.com/p/49f72ead38c5

(讲得比较浅)Binder机制:https://blog.csdn.net/github_37130188/article/details/89857282

安卓跨进程通信Binder详解:https://blog.csdn.net/carson_ho/article/details/73560642

 

学习binder机制时涉及到了一些设计模式的知识:
代理模式:https://www.cnblogs.com/daniels/p/8242592.html

========【接下来梳理整合链接中的知识点】=================

Binder通信模型:

基于C/S结构,定义了4个角色:Server、Client、ServerManager、Binder驱动;

前三者是在用户空间,是无法直接进行交互;Binder驱动属于内核空间;

ServerManager起到Server与Client之间的桥梁作用;

Server的Binder实体对象,将自己的引用注册到ServerManager中。

Client通过特定的key来和这个引用进行绑定;

ServerManager内部自己维护一个类似MAP的表来一一对应;

通过这个key就可以向ServerManager拿到Server的Binder引用了;

但是这里有个问题,最初的Server向ServerManager注册不也要用到进程间通信;

这里有个巧妙的地方在于当ServerManager作为服务端时,它提供了一个特殊的Binder,没有名字也不需要注册;

这个特殊Binder引用在所有客户端都固定为0,无需通过其他手段获得;

Server若要向ServerManager注册自己的Binder就必须通过0这个引用号;

另外如果client和server处于不同的进程的话,client从SM中拿到引用,Binder驱动层返回给Client的实际上是一个代理对象

如果处于同一个进程的话,返回的是当前Binder对象

==================================================

Serializable接口

该接口是Java所提供的一个序列化接口;是一个空接口;为对象提供标准的序列化和反序列化操作;

实现一个对象的序列化,只需要这个类实现了Serializable接口,并声明一个serialVersionUID即可;

甚至这个serialVersionUID也不是必须的,不声明也可以实现序列化,只不过会对反序列化过程造成影响;

一般情况下要在类的声明中指定一个类似的下面的标识:

private static final long serialVersionUID = 231342342305812L

例如User类,实现了Serializable接口的类:

public class User implements Serializable{

private static final long serialVersionUID = 12434234234234L;

public int userId;

public String userName;

public boolean isMale;

...

}

接下来如何对对象进行序列化和反序列化:

//序列化过程

User user = new User(0,"jack",true);

ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("cache.txt"));

out.writeObject(user);

oout.close();

//反序列化过程

ObjectInputStream in = new ObjectInputStream();

User newUser = (User) in.readObject();

in.close();

这个serialVersionUID用来辅助完成序列化和反序列化的;

序列化时会把当前类的UID写入序列化文件中,当反序列化时候系统会去检测文件中的UID,看是否和当前类的UID一致;

如果一致就说明序列化的类版本和当前类的版本是相同的,这个时候可以成功反序列化;

否则就说明了当前类和序列化的类相比发生了某些变换;就会报错;所以是为了预防类发生了修改,这时候反序列化回来时必然出错的,用UID就可以检测错误;

==================================================

Parcelable接口

安卓中提供的新序列化方式;

只要实现这个接口,一个类的对象就可以实现序列化并可以通过Intent和Binder传递;

使用比较复杂:

 1 public class User implements Parcelable{
 2   public int userId;
 3   public String userName;
 4   public boolean isMale;
 5 
 6   public Book book;
 7 
 8   public User(int userId, String userName, boolean isMale){
 9     this.userId = userId;
10     this.userName = userName;
11     this.isMale = isMale;
12   }  
13 
14   public int describeContents(){            //返回当前对象的内容描述,如果含有文件描述符,返回1;否则返回0,几乎所有情况都返回0
15     return 0;
16   }
17 
18   public void writeToParcel(Parcel out, int flags){      //当前对象写入序列化结构中,其中flags标识有两种值;1表示当前对象需要作为返回值返回,不能立即释放资源;0表示不需要,几乎所有情况都属于0
19     out.writeInt(userId);
20     out.writeString(userName);
21     out.writeInt(isMale ? 1 : 0);
22     out.writeParcelable(book, 0);
23   }
24 
25   public static final Parcelable.Creator<User> CREATOR = new Parcelable.Creator<User>(){
26     public User createFromParcel(Parcel in){       //从序列化后的对象中返回创建原始对象
27       return new User(in);
28     }
29 
30     public User[] newArray(int size) {            //创建指定长度的原始对象数组
31         return new User[size];
32     }
33   };
34 
35   private User(Parcel in) {                      //从序列化后的对象中返回创建原始对象
36     userId = in.readInt();
37     userName = in.readString();
38     isMale = in.readInt();
39     book = in.readParcelable(Thread.currentThread().getContextClassLoader());
40   }
41 }

另外系统已经提供了许多实现了Parcelable接口的类,它们都是可以直接序列化的;

比如Intent、Bundle、Bitmap等;

两种序列化接口的比较:

Serializable接口是Java中的序列化接口,其使用起来简单但是开销很大,序列化和反序列化过程需要大量I/O操作。

Parcelable是Android中序列化方式,适合安卓平台,效率比较高,缺点是使用起来比较麻烦;

Parcelable主要用在内存的序列化上;Serializable可以用在存储设备和网络传输的序列化; 

=================================================

Binder

应用层角度来说,Binder是客户端和服务端进行通信的媒介;

当bindService的时候,服务端返回一个包含了服务端业务调用的Binder对象;

通过这个Binder对象,客户端就可以获取服务端提供的服务或者数据,这里的服务包括普通服务、基于AIDL的服务;

Binder通信方式是安卓中提出的,是一种IPC的通信方式;

 

 

原文地址:https://www.cnblogs.com/grooovvve/p/12462295.html