IPC 机制篇

1, Android中进程和线程的关系?区别?

答: 不只是在 Android 中, 进程在操作系统的级别上来说, 是属于操作系统分配资源的最小单位, 是运行在某一片内存地址中的自包容性的程序,   而线程是属于事件调度的最小单位, 它是属于进程中的一个单一的程序控制流,   一个进程往往可以包含多个线程, 对于 Android APP 来说, 一般情况下, 一个 APP 就只有一个进程, 但是我们可以通过在 manifest 文件中指定 process 属性来开启多进程模式.

 

2, 为何需要进行IPC?多进程通信可能会出现什么问题?

答: IPC 本是用来进行进程通信的, 我们之所以需要使用 IPC 是因为我们在通常只有一个进程的 APP 中开启了多进程模式, 把应用不同的模块和功能分别放在不同的进程, 这样做的好处是可以获取更多的内存资源, 降低主进程的压力, 防止 OOM,  在 Android 中开启多进程模式主要会造成如下四点影响:

  1. 静态和单列完全失效.
  2. 线程同步完全失效, 由不同的虚拟机造成.
  3. Shareprefers 不再可靠,  主要是因为 SP 会在内存中存在缓存机制, 开启多进程后,不同的进程完全属于两个不同的虚拟机, 根本就不处于同一块内存中, 所以可能会导致 SP 提交的数据不能马上在另外一个进程获取, 甚至可能出现丢失数据的情况.
  4. application 被启动多次.

 

3, 什么是序列化?Serializable接口和Parcelable接口的区别?为何推荐使用后者?

答: 序列化是指把一个对象转换成可存储或者可传输的状态, 如常见的 把对象保存到文件, 在 Android 四大组件之间传递对象, 或者是在网络上传输一个对象, 这些都需要用到对象的序列化,  实现序列化的两个接口, 

  • Serializable 接口是 java 自带的接口, 其具体的细节是由 java 内部实现的, 是把整个对象进行虚拟化,  其迷人之处它是一个标记接口, 意味着不需要实现任何方法, 但是其因为使用了反射而导致效率较为低下, 主要用在java 的 io 流中保存对象, 或者用于 网络传输, 
  • 至于 Parcelable 接口, 其是 Android 特有的, 其实现原理是把一个对象进行拆分成许多的基本数据类型, 每种类型都是 Intent 或者 Bundle 所支持的类型, 其效率较高, 缺陷是需要书写过多的模板代码,  其主要用于在内存中传递对象, 不适合用来持久化保存对象.

 

4, Android中有哪些基于Binder的IPC方式?简单对比下?

答: 基于 Binder 的 IPC 方式主要有

  • Bundle, 用于四大组件之间的通信, 只能进行数据传输, 不支持 RPC, 使用较为简单.
  • Messenger, 使用过程类似 Handler, 也不支持 RPC, 主要用于数据传输, 支持实时的串行通信.
  • AIDL, 支持 RPC, 功能较为强大, 跨进程的首选, 其缺陷是使用稍为繁琐, 需要处理好客户端线程被挂起的问题.
  • ContentProvider, 其设计的本意是用来在多个 APP 之间共享数据的,  主要对共享的数据提供 crud 操作, 同样也不支持 RPC.

另附 IPC 机制的对比图:

 

 

5, 是否了解AIDL?原理是什么?如何优化多模块都使用AIDL的情况?

答: AIDL 是 Android 接口定义语言, 其主要作用是用来进行 IPC 通信的, 其实现的原理是 idea 会根据我们书写的 AIDL 文件编译生成 java 文件, 而这个 java 文件是通过使用基于 CS  架构的 Binder 来实行进程通信的, 其使用过程和服务有点类似,  因此如果我们我们存在多个业务模块都需要进行进程通信的话, 每一个模块都构建一个服务会显的应用过于重量级, 毕竟服务是四大组件之一, 我们可以通过只使用一个服务, 让这个服务根据调用端传递过来的标识符返回不同的 Binder 对象, 这也就是我们常说的 Binder 连接池,  从而实现多个模块的进程通信.

 

 

6, Android中为何新增Binder来作为主要的IPC方式?

答: 我们之所以感觉 BInder 是 Android 中主要的 IPC 机制, 是因为对于我们应用开发人员来说, 我们接触最为频繁的便是用于应用层的 APP 进程和 系统 进程之间进行 跨进程通信的  Binder 机制,  Android 中也大量的使用了其他 IPC 机制来进行进程通信, 如对于 fork 出所有应用进程的 Zygote 进程和 AMS 之间的跨进程通信便是采用的 Socket, 而对于普通的应用层, 大量采用的 BInder 机制来作为主要的 IPC 机制主要是因为:

  • 安全因素,  应用层的 APP 进程有着不确定性, 而对于 BInder 机制, 很容易在服务端通过验证发起请求的客户端的 UIP 和 PID 来确定该进程是否可靠, 如果不可靠, 可以很便捷的拒绝此次请求, 而对于其他常见的 IPC 机制要保证较高的安全性, 实现较为复杂.
  • 高效性,  在 Linux 常见的 IPC 机制中, 如 管道, 共享内存, socket, 进程间的信号量 等等, 除共享内存外, 其他的大多都需要对数据进行两次拷贝, 而对于和 BInder 拥有差不多效率的 共享内存则因为其架构不如 基于 CS 架构的 Binder 稳定,  基于 CS 架构, 服务端和客户端相互独立, 任何一方出现问题都不会太多的影响到另外一方,  因此中的来说, 对于 应用层,  用 Binder 来作为主要的 IPC 机制也许是最好的选择.

参考博文:  https://www.zhihu.com/question/39440766

 

 

7, 使用Binder进行数据传输的具体过程?

答: 

当我们调用 binderServices 返回一个服务端的  binder 对象后, 然后通过 AIDL 文件生成的 java 类的 asInterface 方法, 来获取我们自定义的 AIDL 文件接口对象, asInterface 会判断是否为本地对象, 即是否位于同一个进程类, 如果不是则会返回一个 Proxy 对象, 这个类也是 AIDL 文件编译后自动生成的类, 该类也实现了我们的AIDL 接口.

 当我们调用 AIDL 接口中具体的业务方法便是调用了 Proxy 类的具体方法, 该类持有了 Binder 对象, 会通过 transcat 方法来向服务端发起请求, 如果有参数, 同时会把参数写入,  当服务端接受到请求后, 便会调用 Stub 子类的 onTranscat 方法, 该方法会根据 标识符 来具体执行某一个业务方法, 在执行的过程中, 客户端线程会挂起, 业务方法执行完成后, 通过 binder 对象, 把返回值写入, 然后会在客户端的 Proxy 发起请求的方法中接受到, 此时客户端被唤醒继续运行, 到此一次 RPC 调用结束. 

 

 



8.Binder框架中ServiceManager的作用?

答:  


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值