IPC机制基础

233 阅读3分钟

一、简介

 IPC(Inter Process Communication),即多进程间通信。

那什么是进程?什么是线程?

进程,是一个具有独立功能的程序关于某个数据集合的一次运行活动,简单来说就是一个执行单元。同时进程又是一个线程的容器。


线程,是cpu调度的最小单位,它几乎不拥有资源,但是与其他线程共享进程中的资源。


在Android中进程可以理解为一个应用。一个应用就是一个进程。在Android中,一个应用只有一个主线程,主线程当中可以操作UI界面,如果在主线程中有大量的耗时任务,那么会造成ANR(application not responding)。ANR在PC中也是常见的问题。因此不阻塞主线程,是每一个Android必须要遵守的约定。

多进程的使用场景在这里不做多阐述,总之很多时候,在APP中很多耗时的后台任务会被放在另一个进程当中。这时候就涉及到两个进程间通信的问题了。

二、如何在APP中开启一个进程

在Android中,正常情况下只有一个办法可以开启新进程,就是在4大组件在manifest中声明时,指定android:process属性。

当然暗黑一点的做法就是,通过JNI 在native 层 fork出一个新的进程,但是没人会这样做的啦。

看下代码,如何去创建一个新进程。

<activity android:name=".MainActivity">
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />

        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
</activity>

<activity
    android:name=".ProcessActivity"
    android:process=":remote" />

<activity
    android:name=".ProcessOneActivity"
    android:process="ProcessOneActivity:remote" />

<activity
    android:name=".ProcessTwoActivity"
    android:process="ProcessTwoActivity.remote" />

可以看到


使用":"的写法声明process时,系统会使用当前的包名来命名当前进程。

com.example.tuoge.aidlt:remote

会作为此进程的名字,是一种简易的写法。并且代表了此进程为私有进程,不可被外界访问。

ProcessOneActivity 

的进程名字为ProcessOneActivity:remote。

ProcessTwoActivity.remote
这种就是属于共有进程,任何人都可以访问,如果没有特殊需求,还是都用:命名自己的进程

三、多进程通信的问题

每一个应用,Android系统便会为它,分配一个独立的虚拟机,也就是说,这两个虚拟机的内存空间是不一样的,访问同一个对象会在各自的内存中产生独立的副本。

总之,不是同一份内存了。。。

像static,单例,sharepreference可靠性下降,Application多次创建。


1.static和单例,根本就不是同一份内存, 自然取到的对象不是同一个,失效。

2.同理1,就是一个进程代表一个应用,自然它的Application会多次创建


四、Serializable 和 Parcelable

Serializable,它是java提供的序列化接口。

Serializable 可以通过声明一个名为serialVersionUID的long的变量标识自己,此变量非必须。

区别在于,反序列化的过程。

如下代码:test 就是一个需要序列化的对象。

序列化

ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("sdfs.text"));
out.writeObject(test);
out.close();

接下来反序列化

ObjectInputStream in = new ObjectInputStream(new FileInputStream("cache.text"));
Test test = (Test)in.readObject();

此时如果Test中没有指定的serialVersionUID变量,会反序列化不成功,因为serialVersionUID是用来标识具体的对象,不是同一个对象,便无法反序列化成功。


Parcelable

parcelable是Android提供的更轻量级的传输接口,用于binder中传输数据。

parcelable与serializable的区别

我们从以下3点来考虑:

1.在进程间传递对象

2.在网络中传递对象

3.永久保存对象,将对象写入磁盘


serializable会开销大一些,因为会涉及到大量的IO操作,以及各种反射操作产生的大量临时变量。parcelable使用比较麻烦,但是效率比较高,而且是android平台的接口,适合在android平台上使用。不过parcelable在将对象写入磁盘上不支持。