• 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的通信方式;

     

     

  • 相关阅读:
    学Python要避免哪些坑,如何巩固好基础
    Python爬虫:现学现用xpath爬取豆瓣音乐
    福州大学软件工程1816 | W班 第10次作业[软件工程实践总结]
    福州大学软件工程1816 | W班 第10次作业[个人作业——软件产品案例分析]
    福州大学软件工程1816 | W班 第8次作业[团队作业,随堂小测——校友录]
    福州大学软件工程1816 | W班 第6次作业WordCount成绩排名
    福州大学软件工程1816 | W班 第4次作业(团队展示)成绩排名
    福州大学软件工程1816 | W班 第2次作业成绩排名
    软件工程github使用小结
    2018北航软工教学培训小结
  • 原文地址:https://www.cnblogs.com/grooovvve/p/12462295.html
Copyright © 2020-2023  润新知