===========【对象序列化】==========================
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的通信方式;