Android IPC机制

IPC(进程间通信或者跨进程通信):指两个进程间交换数据的过程。

线程:线程是CPU调度的最小单位,是一种有限的系统资源。
进程:进程一般指一个执行单元,在PC或者移动设备上指一个程序或者应用。
一个进程可以包含多个线程,最简单情况下,一个进程只包含一个线程(即主线程)。Android中主线程也叫作UI线程。

Android中的多进程模式

Android中只能通过给四大组件指定 android:process 属性,来可以开启多进程模式
特殊情况,还有一种非常规的多进程方法:通过JNI在native层去fork一个新进程

开启多进程模式

正常情况下,在Android中多进程是指一个应用中存在多个进程的情况。
在指定android:process属性值里面指定当前组件运行在那个进程,指定的时候其中的“ : ”表示在当前进程前附加当前包名,另一种就是完整的声明方式,直接直接定具体进行名

多进程模式的运行机制

所有运行在不同进程中的四大组件,只要他们之间需要通过内存来共享数据,都会共享失败,这也是多进程带来的主要影响。
一般来说,使用多进程会造成如下几方面问题:

  • (1)静态成员和单例模式完全失效
  • (2)线程同步机制完全失效,不同进程针对的是不同对象
  • (3)SharedPreference可靠性下降,不支持两个进程同时执行写操作,否则会造成一定几率的数据丢失
  • (4)Application会多次创建

IPC基础概念

主要包含三个方面内容:serializable接口、Parcelable接口、Binder
serializable和Parcelable接口,可以完成对象的序列化过程,当我么你需要通过Intent和Binder传输数据时就需要用到

Serializable接口

Serializable接口是Java所提供的一个序列化接口,它是一个空接口,为对象提供标准的序列化和反序列化操作。使用的时候在类的声明中实现Serializable接口即可,或者再声明一个私有静态常量serialVersionUID,系统会自动实现默认序列化。
serialVersionUID作用:序列化的时候写入文件,当反序列化的时候系统会去检测文件中的serialVersionUID是否一致,如果一致就说明序列化的类版本和当前类的版本相同,这时候可成功反序列化;否则就说明发生了一些改变,就无法反序列化。
如何进行对象的序列化和反序列化,只需要采用ObjectOutPutStream和ObjectInputStream即可

需要注意的是:静态成员变量属于类,不属于对象,所以不会参与序列化过程;其次还可以使用transient关键字标记成员变量不参与序列化过程。
另外,序列化和反序列化的实现过程也是可以改变的,需要重写writeObject()和readObject()方法

Parcelable接口

Parcelable接口,只要实现这个接口,一个类的对象就可以实现序列化,并通过Intent和Binder传递。
首先说一下Parcel,内部包装了可序列化的数据,可以在Binder中自由传输,在序列化过程中,需要实现的功能有序列化、反序列化和功能描述。
序列化功能由writeToParcel()完成,最终通过Parcel的一系列write方法来完成。
反序列化功能由CREATOR完成,其内部标明了如何创建序列化对象和数组,并通过Parcel的一些列read方法来完成
内容描述功能由describeContents方法完成,几乎所有情况这个方法都应该返回0,仅当当前对象中存在文件描述符时,返回1

Serializable和Parcelable的区别
  • Serializable是Java中的序列化接口,使用简单但是开销大,序列化和反序列化过程需要大量I/O。会创建大量的临时变量,从而引起频繁GC
  • Parcelable是Android中的序列化方式,缺点是使用稍微麻烦点,但是效率高。主要用在内存序列化上,通过Parcelable将对象序列化到存储设备中或者将对象序列化过后通过网络传输,但是这个过程稍微复杂,所以这两种情况推荐使用Serializable

Binder(使用和上层原理)

直观来说,Binder是Android的一个类,实现了Binder接口。从IPC角度来说,Binder是Android中的一种跨进程通信方式。
Android开发中,Binder主要用于Service中,包括AIDL和Messenger,其中普通的Service中不涉及进程通信,就比较简单,而Messenger底层是AIDL,所以针对AIDL来讲解Binder

创建AIDL文件后,系统会自动生成一个对应的Java类,其中包含两个核心实现类,内部stub类和stub的内部类Proxy,这两个类的每个方法含义详解如下:

  • DESCRIPTOR:Binder的唯一标识,一般用当前Binder的类名表示
  • asInterface(android.os.IBinder obj):用于将服务器的Binder对象转换成客户端所需AIDL接口类型对象,这种转换过程是区分进程的,如果客户端和服务器位于统一进程,那么此方法返回的就是服务器端的Stub对象本身,否则就是返回系统封装的Stub.Proxy对象
  • asBinder:用于返回当前Binder对象
  • onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flag):此方法运行在服务端的Binder线程中,当服务器发起跨进程请求时,远程请求会通过系统底层封装后交由此方法处理。code用于确定客户端所请求的目标方法是什么,接着从data中取出目标方法所需参数,然后执行目标方法,执行完成后返回值写入reply中。如果此方法返回false,那么客户端请求失败
  • Proxy#XXX方法:运行在客户端,当客户端远程调用此方法时:内部会首先创建该方法所需要的输入型Parcel对象_data、输出型Parcel对象_reply和返回值对象,然后将参数信息写入_data中(如果有参数的话),接着调用onTransact()发起RPC请求(远程过程调用),同时当前线程挂起;然后服务器onTransact()方法调用,直到RPC返回后当前线程继续执行。
注意:当客户端发起远程请求时,由于当前线程会被挂起直至服务端进程唤醒并返回数据,所以如果远程方法很耗时,那么不能在UI线程中发起远程请求;由于服务器的Binder方法运行在Binder线程池中,所以不管Binder方法是否耗时都应采用同步的方式实现

Binder设置死亡代理

1、首先声明一个DeathRecipient对象,DeathRecipient是一个接口,内部只有一个方法binderDied,当binder死亡时,就会调用此方法,然后移除之前的Binderd代理并重新绑定远程服务。
2、然后在客户端绑定远程服务后,给binder设置死亡代理:binder.linkTodeath(DeathRecipient, 标志位)
这样设置好过后,当Binder死亡过后,就可以收到通知;另外还可以通过Binder的isBinderAlive()判断Binder是否死亡。

Android中的IPC方式

1、Bundle

四大组件中Activity、Service、Receiver都支持在Intent中传递Bundle数据,由于Bundle实现了Parcelable接口,所以可以在不同进程间传递。
Bundle支持的数据类型:基本数据类型,实现了Parcelable接口和Serializable接口的对象,以及Android支持的特殊对象。

2、文件共享

文件共享也是一种进程间的通信方式,两个进程通过读写同一文件来交换数据。Windows上,一个文件如果被加了排斥锁就会导致其他线程无法访问其数据,而Android基于Linux,并没有对并非读写文件有所限制。
文件共享方式共享数据对文件格式没有具体要求,只要读写双方约定数据格式即可。这种方式也是有局限性的,比如说:并发读写时,获取的数据可能不是最新的。因此需要妥善处理并发读写的问题。
SharedPreference是个特例,在多进程下,读写操作就会变得不可靠,面对高并发的读写访问就可能丢失数据。因此不建议在进程通信中使用SharedPreference

3、Messenger

Messenger可以在不同进程中传递Message对象,在Message中放入需要传递的数据。
Messenger是一种轻量级的IPC方案,底层实现是AIDL,对AIDL进行了封装。
实现Messenger步骤,分为客户端和服务器端:

  • 服务端进程
    服务端创建一个Service来处理客户端的连接请求,同时创建一个Handler并通过它创建一个Messenger对象,然后再Service的onBind方法中返回这个Messenger对象底层的Binder即可。

  • 客户端进程
    客户端进程首先绑定服务端的Service,绑定成功后用服务端返回的IBinder对象创建一个Messenger,通过这个Messenger向服务器端发送消息,消息类型为Message对象。如果需要服务端回应,则需要在客户端创建一个Handler,并创建一个新的Messenger,并把这个Messenger对象通过Message的replyTo参数传递给服务端,服务端通过这个replyTo就可以回应客户端。

4、AIDL

AIDL实现进程通信流程分为客户端和服务端:

  • 1、服务端
    服务端创建一个Service监听客户端的连接请求,然后创建一个AIDL文件,将暴露给客户端的接口在这个AIDL文件中声明,最后在Service中实现这个接口
  • 2、客户端
    绑定服务端的Service,绑定成功后,将服务端返回的Binder对象转换成AIDL接口所属类型,然后就可以调用AIDL中的方法。
  • 3、AIDL接口的创建
    在AIDL文件中,AIDL所支持的数据类型:
    (1)基本数据类型
    (2)String和CharSequence
    (3)List:只支持ArrayList,里面每个元素都必须能够被AIDL支持
    (4)Map:只支持HashMap,里面的每个元素都必须被AIDL支持,包括key和value
    (5)Parcelable:所有实现了Parcelable的对象
    (6)AIDL:所有AIDL接口本身也可以在AIDL中使用
    后续两种数据需要显示的import导入。

5、使用ContentProvider

ContentProvider是Android专门提供用于不同进程间数据共享的方式,底层实现同样是Binder
ContentProvider的使用参考——Android第一行代码

6、使用Socket

Socket称为套接字,网络通信中的概念,分为流式套接字和用户数据报套接字也就是TCP和UDP

Binder连接池

AIDL使用大致流程:首先创建一个Service和AIDL接口,接着创建一个类继承自AIDL接口中的Stub类并实现Stub中的抽象方法,在Service的onBind方法中返回这个类的对象,然后客户端就可以绑定服务端的Service,建立连接后就可以访问远程服务端的方法了。
Binder连接池的主要作用:将每个业务模块的Binder请求统一转发到远程Service中执行,从而避免了重复创建Service的过程。

选择合适的IPC方式

最后

如果想要成为架构师或想突破20~30K薪资范畴,那就不要局限在编码,业务,要会选型、扩展,提升编程思维。此外,良好的职业规划也很重要,学习的习惯很重要,但是最重要的还是要能持之以恒,任何不能坚持落实的计划都是空谈。

如果你没有方向,这里给大家分享一套由阿里高级架构师编写的《Android八大模块进阶笔记》,帮大家将杂乱、零散、碎片化的知识进行体系化的整理,让大家系统而高效地掌握Android开发的各个知识点。
img
相对于我们平时看的碎片化内容,这份笔记的知识点更系统化,更容易理解和记忆,是严格按照知识体系编排的。

欢迎大家一键三连支持,若需要文中资料,直接扫描文末CSDN官方认证微信卡片免费领取↓↓↓(文末还有ChatGPT机器人小福利哦,大家千万不要错过)

PS:群里还设有ChatGPT机器人,可以解答大家在工作上或者是技术上的问题
图片

  • 20
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Android IPC(Inter-Process Communication)机制是指在Android系统中,不同进程之间进行通信的方式。Android中的应用程序通常都运行在自己的进程中,如果不同应用程序之间需要进行通信,或者同一个应用程序的不同进程之间需要进行通信,就需要使用IPC机制Android系统提供了多种IPC机制,包括: 1. Intent:Intent是一种轻量级的IPC方式,可以用来实现不同应用程序之间的通信。通过发送Intent,可以启动其他应用程序的Activity或Service,或者在不同应用程序之间传递数据。 2. Binder:Binder是一种基于进程间通信(IPC)的机制,它是Android系统中进程间通信的基础。通过Binder,可以在不同的进程之间传递对象、调用远程方法等。 3. ContentProvider:ContentProvider是Android中一种特殊的组件,用于在不同的应用程序之间共享数据。通过ContentProvider,可以将数据存储在一个应用程序中,然后在其他应用程序中访问这些数据。 4. Messenger:Messenger是一种轻量级的IPC方式,它基于Binder实现。通过Messenger,可以在不同进程之间传递Message对象。 5. AIDL(Android Interface Definition Language):AIDL是一种专门用于Android的IDL语言,它可以定义跨进程通信(IPC)接口。通过AIDL,可以在不同进程之间传递复杂的数据结构。 6. Socket:Socket是一种基于网络的IPC方式,可以在不同的设备之间进行通信。通过Socket,可以在不同的进程或设备之间传递数据。 以上是Android中常用的IPC机制,不同的IPC机制适用于不同的场景。开发者需要根据具体的需求选择合适的IPC机制

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值