androidIPC

来源:互联网 发布:淘宝2016年全年销售额 编辑:程序博客网 时间:2024/06/05 06:13

主要参考:android开发艺术探索
1.基本介绍:
多进程不是android所特有的,android中最有特色的进程间通信方式就是Binder了。android也支持在两个终端中使用socket进行通信。android中多进程通信的使用场景可以分为两种,一种是一个应用中使用对进程,比如有些模块因为某个模块某些原因需要运行在单个进程中,又或者这个应用需要更大的运行内存(android对于每个应用所能应用的最大内存做了限制);另一种就是在两个应用之间进行通信,比如我们经常用到的contentProvider就是一种IPC方式
2.android中的多进程

一般我们讨论的多进程指的是一个应用中存在多个进程,因此我们不讨论两个应用之间的多进程情况

那么如何在android中开启一个新进程呢?
在android中开启一个新进程的方法只有一个,就是在android的menifest文件中,给四大组件指定android:progress属性,该属性表示该组件在哪个进程中运行。如果没有该属性,那么默认在以包名为名的进程中运行。
效果如下:

  <application        android:name=".application.BaseApplication"        android:allowBackup="true"        android:icon="@mipmap/ic_launcher"        android:label="@string/app_name"        android:supportsRtl="true"        android:theme="@style/AppTheme">        <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=".ui.SecondActivity"            android:process=":remote">        </activity>        <activity android:name=".ui.ThirdActivity"            android:process="com.mooc.prac.home">        </activity>    </application>

将这三个activity加载后,运行结果如下:
这里写图片描述
如图,就会有三个进程出现。
细心的童鞋就会发现,我们在第二个activity中的progress属性写为了:remote,但是结果com.mooc.prac:remote。以:开头的进程意味着该应用的私有的进程,其他应用的组件是不能与该进程共同运行在同一进程的。不以:开头的进程为全局进程,我们可以通过ShareUID的方式使他们运行在同一进程。
android多进程的创建就是如此简单,但是android的多进程会导致很多问题。
看个例子:
我们在一个类中写一个静态对象:

public class QiPao{    public static int qipaoNum = 1;}

继续同上文的activity,先用activity1修改它为二,activity2在访问他。结果如何呢?
这里写图片描述
why!!!?

应该知道的是:android虚拟机会为每个进程分配一个独立的虚拟机,不同的虚拟机在内存中分配有不同的地址空间,要准确理解这个问题,也就必须知道什么叫做地址空间?

进程的本质是一个正在执行的程序,而与每个进程相关的就是它的地址空间,这是从某个最小的存储的位置(一般是零)到某个最大存储位置的列表。在这个地址空间中,程序可以进行读写,这个地址空间中存放有可执行的程序,程序的数据和堆栈。

不难看出,正是因为android虚拟机给每个程序分配有独立的虚拟机也就是有了独立的地址空间,这也就导致不同的虚拟机去访问应用里的共享数据会产生多个副本,于是就导致了如下问题:

1.静态对象和单例模式失效
2.线程同步机制失效
3.sharedPreference可靠性下降
4.Application会被多次创建。

段落总结:
当一个组件运行在一个新进程中时,android虚拟机会给他分配一个独立的虚拟机也就是意味着每个新进程有新的地址空间,所以这个过程也就相当于启动了一个新应用。
3.IPC基础概念
但我们在进行intent和Binder进行数据传输的时候,所传输的数据必须是Serializble或者preceble的。
1)Serializble接口
这个东西很简单我就简单说说,需要明白序列化和反序列化的概念,不懂得童鞋百度

1.一个对象实现了Serializble接口,意味着它可以进行序列化和反序列化,Serializble接口是空的,也就是说这只是一个标志,并不需要实现相关方法。
2.可以在类中书写如下标识:

private static final long serialVersionUID = 2221321341654L;

数字随便写,主要应用在反序列化的时候进行确认是否是同一个类。也可以不写,系统会自己更具当前类的结构进行定义,不过这个时候当一个类有所改变的时候,可能就不能确认为同一个类,导致反序列化失败。

2).preceble接口
这个也比较简单,但是繁琐,我就不说了,同学可以自行百度,后期有时间我再加上。
今天就说到这里,后面还有Binder等内容,下一篇在讲,不过这里先贴一张Binder内部执行流程图:
这里写图片描述

原创粉丝点击