Android开发艺术探索(研读笔记)——03-Android中的IPC机制(一)

Android开发艺术探索(研读笔记)

  • 博客:Dimon
  • GitHub:Dimon94

03-Android中的IPC机制(一)

1.Android IPC 简介

IPC(Inter-Process-Communication):含义为进程间通信,指两个进程之间进行数据交换的过程。

什么是进程:一般指一个执行单元,在PC和移动设备上的一个程序或者一个应用。
什么是线程:线程是CPU调度的最小单元,是一种有限的系统资源。

而一个进程可以包含多个线程。

2.Android中的多进程模式

只需要给四大组件指定 android:process 属性,就可以开启多进程模式。(非常规的方法,JNInative层去fork一个新的进程)

//没有定义默认进程的进程名为包名:"com.dimon"
android:process=":remote"  ->  进程名:"com.dimon:remote" 用":"开头的进程属于当前应用的私有进程
android:process="com.dimon.remote"  ->  进程名:"com.dimon.remote" 全局进程

私有进程:其他应用的组件不可以和它跑在同一个进程中。

全局进程:其他应用通过ShareUID(每个应用都有自己唯一的UID,具有相同UID的应用才能共享数据)方式可以和它跑在同一个进程。同个应用间的多进程可以理解为两个不同的应用采用了ShareUID模式。

除了DDMS视图查看进程外,还可以用shell来查看,命令为:adb shell ps 或者 adb shell ps|grep com.dimon(com.dimon是包名)

多进程会造成的问题

  • 静态成员和单例模式完全失效:主要是每个进程都分配了一个独立的虚拟机,不同的虚拟机在内存分配上有不同的地址空间;
  • 线程同步机制完全失效:因为不是同一块内存所以无法保证线程同步了;
  • SharePreferences的可靠性下降:SharePreferences底层是通过读/写XML文件来实现的,并发写可能会出现问题,也就是说其不支持两个进程同时去执行写操作;
  • Application会多次创建

Serializable接口

SerializableJava所提供的一个序列化接口。

public class User implements Serializable{
  private static final long serialVersionUID = 519067123721295773L;//反序列化的时候系统会检测是否版本相同,相同才可以算成功反序列化,不相同则会反序列化失败

  public int userId;
  public String uesrName;
  public boolean isMale;
  ...
}
//序列化过程
User user = new User(0, "jake", true);
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();
  • 静态成员变量属于类不属于对象,所以不会参与序列化过程;
  • transient关键字标记的成员变量不参与序列化过程;

Parcelable接口

典型用法:

public class User implements Parcelable {
  public int uesrId;
  public String uesrName;
  public boolean isMale;

  public Book book;

  public User(int userId, String uesrName, boolean isMale) {
    this.userId = userId;
    this.uesrName = uesrName;
    this.isMale = isMale;
  }
// 内容描述功能:对象存在文件描述符时,方法1
  public int describeContents() {
    return 0;
  }

// 序列化功能
  public void writeToParcel(parcel out, int flags) {
    out.writeInt(userId);
    out.writeString(uesrName);
    out.writeInt(isMale ? 1 : 0 );
    out.writeParcelable(book, 0 );
  }

// 反序列化功能
  public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
    public User createFromParcel(Parcel in) {
      return new User(in);

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

    private User(Parcel in) {
      userId = in.readInt();
      uesrName = in.readString();
      isMale = in.readInt() == 1;
      // 传递当前线程的上下文类加载器
      book = in.readParcelable(Thread.currentThread().getContextClassLoader());
    }
  }
}

parcelable 与 Serializable的对比

  • Serializable是Java中的序列化接口,其使用起来简单但是开销很大,序列化和反序列化过程需要大量I/O操作。
  • Parcelable是Android中的序列化方式,缺点就是使用起来稍微麻烦点,但是它的效率很高,是Android推荐的序列化方式。

Android平台上,推荐Parcelable,但在将对象序列化到存储设备或者将对象序列化后通过网络传输建议使用Serializable


  • Good Luck!

你可能感兴趣的:(Android开发艺术探索(研读笔记)——03-Android中的IPC机制(一))