美文网首页
IPC机制(一)——IPC基础概念

IPC机制(一)——IPC基础概念

作者: 李die喋 | 来源:发表于2019-10-05 13:04 被阅读0次

Android中的多进程

IPC学过操作系统的都应该知道,就是进程间通信或者跨进程通信。Android是基于Linux内核的移动操作系统,它的进程间通信方式并不是完全继承于Linux,它有自己的进程间通信方式。

多进程通信的主要方式

  • Binder
  • Bundle
  • 文件共享
  • AIDL
  • Messenger
  • ContentProvider
  • Socket

开启多进程模式

Android中使用多进程只有一种方法,就是给四大组件在AndroidMenifest中指定android:process属性,除此之外没有其他办法。但有一种非常规的办法就是通过JNI在native层去fork一个新的进程。fork在linux系统上就可以尝试。

<activity>
    <android:process=":remote"/>
    或者
    <android:process="com.lxy.ipc.remote"/>
</activity>

两种方式的区别:

以“:”开头的是一种简写的方法,完整的进程名称是com.lxy.ipc:remote。也就是在当前进程名前加上了当前的包名。且以“:”开头的进程属于当前进程的私有进程,其它应用组件不可以和它跑在同一进程中。

第二中命名方式是完整的命名方式,不会附加包名信息,属于全局进程,其它应用可以通过sharedUserID和它跑在同一进程中。

//第一个程序的menifest文件
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.lxy.client"
    android:versionCode="1"
    android:versionName="1.0"
    android:sharedUserId="com.lxy.share">
    
//第二个程序的menifest文件
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.lxy.service"
    android:versionCode="1"
    android:versionName="1.0"
    android:sharedUserId="com.lxy.share">   

多进程模式的运行机制

在学操作系统的时候我们知道每一个进程的都有自己的进程控制块(PCB),android在多进程模式中,不同进程的组件有自己独立的虚拟机、Application、内存空间

举个例子来说:

UserManager类中有一个静态变量

public static int userId = 1;

按理来说静态变量应该是被所有地方共享的,在一个进程中进行加一操作,在其他进程打印,发现结果为1。这说明多进程不是添加了一个android:process属性这么简单。每一个进程都有一个独立的虚拟机,不同的虚拟机在内存分配上有不同的地址空间,这会导致在不同的虚拟机中访问同一个类对象(静态变量属于类对象)会产生多份副本

不同进程中的组件几乎都需要共享数据。使用多进程会造成如下几方面的问题:

  • 静态成员和单例模式完全失效

分配不同的虚拟机,产生多个对象副本

  • 进程同步机制完全失效

不在同一块内存中,所以锁对象和锁全局类都达不到效果

  • SharedPreferences的可靠性下降

SP不支持两个进程同时执行写操作,否则会导致数据一定几率的丢失。SP的底层是通过读写XML来文件实现的,并发写/读都可能出现问题。

  • Application会多次创建

创建新的进程就是要分配独立的虚拟机,所以就是启动一个新的应用的过程,重新启动就会创建新的Application。

Serializable

Serializable是java提供的一个序列化接口,是一个空接口。

public class User implements Serializable {
    private static final long serialVersionUID = 1L;
    private String name;
    private int age;
    、、、
}

序列化和反序列化过程:

//序列化
User user = new User("ldd",20);
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("cache.txt"));
out.writeObject(user);
out.close();

//反序列化
ObjectInputStream in = new ObjectInputStream(new FileInputStream("cache.txt"));
User newUser = (User) in.readObject();
in.close();

序列化就是:将对象转化为字节序列的过程

反序列化就是:将字节序列恢复为java对象

在User类中有一个变量serialVersionUID是用来辅助序列化的过程。原则上序列化后的数据中的serialVersionUID只有和当前类的serialVersionUID相同才能够被反序列化。当我们不指定它的值时,可以让编译器根据当前类的结构去生成它的值,但是这样容易出现错误。比如,当前对象序列化后,更改了类中的变量,再反序列化的时候就会出现错误。因为更改类后会重新生成一个新值。所以一般serialVersionUID的值手动设置,类改变了反序列化也不会出错。

注意:

  • 静态变量属于类不属于对象,不会参与序列化过程
  • 用transient关键字标记的成员变量不参与序列化过程

Parcelable接口

实现这个接口,一个类的对象就可以实现序列化并可以通过Intent和Binder传递。

public class User implements Parcelable {
        private String name;
        private int age;
        private Book book;

        public User(String name,int age){
            this.name = name;
            this.age = age;
        }

        protected User(Parcel in) {
            name = in.readString();
            age = in.readInt();
            book = in.readParcelable(Thread.currentThread().getContextClassLoader());
        }

        public static final Creator<User> CREATOR = new Creator<User>() {
            @Override
            public User createFromParcel(Parcel in) {
                return new User(in);
            }

            @Override
            public User[] newArray(int size) {
                return new User[size];
            }
        };

        @Override
        public int describeContents() {
            return 0;
        }
        
        /**
        *Parcel内部包装了可序列化的数据
        *将当前对象写入序列化结构中
        *flags == 1:表示当前对象需要作为返回值返回
        * flags == 0:几乎所有情况都为0
        */
        @Override
        public void writeToParcel(Parcel dest, int flags) {
            dest.writeString(name);
            dest.writeInt(age);
            dest.writeParcelable(book,0);
        }
}

序列化过程实现的工能:

  • 序列化

writeToParcel(Parcel out,int flags)

  • 反序列化

由CREATOR完成,内部创建了序列化对象和数组。

  • 内容描述

describeContents

返回当前对象的内容描述符(FileDescriptor)。若有返回1,若无返回0。一般都返回0。

Serializable和Parcelable比较

Serializable Parcelable
使用简单但开销大 使用复杂但效率高
需要大量I/O操作 用在内存序列化上(存储设备、网络传输)

相关文章

  • Android Binder机制,共享内存实现原理

    导读 移动开发知识体系总章(Java基础、Android、Flutter) IPC机制简介 IPC基础概念介绍 B...

  • IPC机制(一)——IPC基础概念

    Android中的多进程 IPC学过操作系统的都应该知道,就是进程间通信或者跨进程通信。Android是基于Lin...

  • IPC机制(上)

    目录 Android IPC简介 Android中的多进程模式 IPC基础概念介绍 Android IPC简介 I...

  • 进程化

    一、基础 IPC机制 -- 基础知识 -- 多进程模式 二、使用

  • android IPC机制讲解(二)

    IPC基础概念介绍 介绍一下IPC中的一些基础概念,主要包含三个方面内容:Serializable接口,Parce...

  • Android 关于IPC机制的理解(二)

    上篇文章介绍了IPC机制的基本概念以及简单使用,文章链接:Android 关于IPC机制的理解(一) 这篇文章主要...

  • IPC基础概念介绍

    2.3 IPC基础概念介绍 本节主要介绍IPC中的一些基础概念,主要包含三方面的内容;Serializable接口...

  • Android IPC机制

    1. IPC基础概念——多进程 IPC是Inter Process Communication的缩写,意为进程间通...

  • 要点提炼|开发艺术之IPC

    在上一篇Window里提及过IPC,本篇将详细总结IPC,知识点如下: IPC基础及概念多进程模式序列化Seria...

  • Android IPC机制详解(一)

    本文主要从以下几个方面来介绍IPC机制1、什么是IPC2、Binder机制原理3、AIDL实现 一、什么是IPC ...

网友评论

      本文标题:IPC机制(一)——IPC基础概念

      本文链接:https://www.haomeiwen.com/subject/xlgepctx.html