Android进程通信机制(IPC机制)

一、IPC介绍

IPC,是进程之间通信或跨进程通信,为Inter-Process Communication得缩写,IPC也不是Android所独有得,任何一个操作系统都需要有相应的IPC机制。
IPC应用的场景,既然是进程间通信,那就一定是多进程的场景下才考虑,比如某些工作需要运行在独立的进程中,或者利用多进程,开辟更大的内存空间等。Android中最有特色的进程间通信方式是Binder,除了Binder,还有Socket,管道、信号量、文件共享。
二、Android中的多进程模式

1.开启多进程模式

Android中多进程,一般是单个应用中存在多个进程的情况,当然也存在多个应用的情况,本文记录单进程方式。
正常情况下,需要给四大组件(Activity、Ser、Receiver、Content Provider),在Androidmenifest中指定android:process属性,除此,别无他法,除非以非正常方式,通过JNI在native层,fork一个进程。所以我们无法给一个线程或者一个实体类,指定其运行是的新进程。如下:
在这里插入图片描述
上面三个activity,将SencondActivity和Third Activity 指定不同的process属性,当启动mainactivity时,启动一个进程,当启动Second Activity时,启动"com.ryg.chaper_2:remote"进程,当Third Activity启动时,启动"com.ryg.chapter_2.remote",当然,mainActivity还是运行在默认进程,进程名是包名。注意,以":"开头的进程,是当前私有进程,其他应用的组件无法和它跑在一起,此外为全局进程,其他应用可以通过ShareUID方式和它跑在一起。当然也有限制条件,必须是Share UID相同,并且,签名也相同才可以,这种情况下,还可以访问彼此的私有数据,例如data目录,组件信息等。

2.多进程会造成的问题

  1. 静态变量和单例模式,完全失效
  2. 线程同步机制完全失效
  3. SharedPreferences的可靠性下降
  4. Application会多次创建

问题1.假如在上面例子中,加一个类,并添加静态变量,我们在Second Activity中修改,在ThirdActivity中查看,会发现,静态变量依旧没变化。因为每个进程,都有单独的虚拟机,而jvm都会分配单独的内存,所以,类和静态变量,都是独立的。所有后面,我们再学习,进程的数据共享。
问题2.本质上和第一个问题一样,不是同一块内存,当然锁对象还是锁全局,都不能保证线程同步。
问题3.SharedPreferences不支持多京城同时去执行写操作,应为它本身是通过读写xml文件实现的,显然并发会导致读写失败。
问题4.由于系统创建新进程的同时,会分配一个独立的虚拟机,所以这个过程也是重新启动一个应用的过程,当然应用也会启动一遍,那么,application 也会启动一次,可以通过上面例子,在application的oncreate打印进程名称来验证。

二、IPC的基础概念

基础概念主要包括三方面内容:Serializable接口、Parcelable接口以及Binder,其中Serializable和Parcelable接口可以完成对象的序列化过程,当我们通过Intent和Binder传输数据时,就要用到Serializable或者Parcelable。还有可能我们需要对象,持久化到设备中,或者通过网络传输给其他客户端,这事就需要Serializable完成对象的持久化。

1.Serializable接口

在这里插入图片描述

在这里插入图片描述

Serializable是Java 提供的一个序列化接口,在Android中是Parcel able接口,后面介绍。可以看到它是一个空接口,序列化和反序列化如下:

在这里插入图片描述
这里有个serializableUid,它到底是什么含义,serializableUid类似与一个索引,没有serializableUid,序列化可以实现,但反序列化,会失败。原则上,序列化后的数据中,serializableUid和当前类的serializableUid相同,才能被反序列化,还有当前类变量成员、类型发生变化,也是无法正常反序列化的,会报异常。

2.Parcelable接口

源码

在这里插入图片描述

序列化和反序列化

一个类只要实现Parcelable这个接口,就可以实现序列化和反序列化,并可以通过Intent和Binder传递,典型用法如下:

@SuppressLint("ParcelCreator")
class User implements Parcelable {
    private String userName;
    private String userAddress;
    private  Info info;
    public User(String name, String address) {
        this.userName = name;
        this.userAddress = address;
    }

    @Override
    public int describeContents() {
        return 0;
    }

	//序列化
    @Override
    public void writeToParcel(@NonNull Parcel out, int flags) {
        out.writeString(userName);
        out.writeString(userAddress);
        out.writeParcelable((Parcelable) info,0);
    }
    
    //反序列化
    public static final  Parcelable.Creator<User> CREATOR = new Creator<User>() {
        @Override
        public User createFromParcel(Parcel in) {
            return User(in);
        }

        @Override
        public User[] newArray(int size) {
            return new User[size];
        }
    };
    //Parcelde.read方法实现反序列化
    public User(Parcel in){
        userName = in.readString();
        userAddress = in.readString();
        info = in.readParcelable(Thread.currentThread().getContextClassLoader());
    }
}

Parcel内部封装了可序列化的数据,可以在Binder中传输。序列化用writeToParcel方法实现,最终由Parcel内部的一系列write方法实现。反序列化由CREATOR来完成,其内部标明了如何创建序列化对象和数组并通过Parcel的read方法实现。注意,实体类需要User(Parcel in)方法中,info是一个可序列化对象,所以需要传递当前线程的上下文才可以,不然会报类找不到的错误。Parcelable相关方法描述如下:
在这里插入图片描述

Serialazeble和parcelable的区别和优缺点

  • Serialazeble是Java中的序列化接口,使用简单,但开销大,由大量的IO操作
  • Parcelable是Android中的序列化方法,使用比较麻烦,但使用效率高,Parcelable是序列化到存储设备中或者将对象序列化后通过网络传输。

3、Binder

在这里插入图片描述
看到书中这句话,让我倒吸一口凉气!!!,继续吧,从三个方面了解

  • IPC角度来说,Binder是Android中的一中跨进程通信方式的一个类,集成IBinder接口,也可以理解为一种,以/dev/binder为驱动的虚拟物理设备;
  • Android FrameWork角度来说,Binder是Servicemanager连接Manager(ActivityManager、WindowManager…)和相应ManagerService的桥梁;
  • Android应用层来说,Binder是服务端和客户端进行通信的媒介,当bindService的时候,服务端会返回一个包含了服务端业务调用的Binder对象,通过这个对象,客户端可以从服务端获取数据或服务端提供的服务,包括普通服务和基于AIDL的服务。
    Android 开发中,Binder主要用在service中,包括AIDL和Messager,其中普通的Service中的Binder不涉及进程间通信,而Messager的底层是通过AIDL,所以我们用AIDL示例来学习Binder工作过程。关于AIDL的相关使用可以移步到Android进程通信-AIDL,相关内容,后续慢慢更新。

特别声明:内容总结来源《Android开发艺术探索》,仅记录学习,如有侵权或不对之处,还请告知,定当删除或改正

  • 12
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
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机制

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

这个Bug有点难搞

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值