0.  前言

不论是Android还是其他操作系统,都会有自己的IPC机制,所谓IPC(Inter-Process Communication)即进程间通信。首先线程和进程是很不同的概念,线程是CPU调用的最小单元,进程一般在PC和移动设备上指一个程序或者一个应用,一个进程可以包含多个线程。Android在一个应用中可以通过android:process属性开启多进程模式,用于某些模块必须运行在单独进程中或为一个应用多申请点内存。关于多进程的使用场景,详情可以参考Android开发——Android多进程以及使用场景介绍

该属性若以“:”开头则该进程属于当前应用的私有进程,否则属于全局进程。

虽然名为私有进程,但是可以为其再声明一个android:exported="true"属性,然后增加intent-filter属性(如果没有intent-filter属性,只能在本应用内使用),其他应用也可以关联到这个进程。

全局进程中假设有多个应用都有声明了android:process="com.XX"全局进程的组件,会产生多个名字相同但PID并不相同的进程,所以全局进程并非全局唯一的意思。全局进程的作用是,其他应用可以通过ShareUID的方式和这个全局进程跑在同一个进程上,从而共享资源。

IPC方式有很多,在Android中常用的IPC方式包括Bundle、文件、Messenger、AIDL、ContentProvider和Socket等方式。

本篇主要讲解使用Bundle和文件的方式。本文原创,转载请注明出处为SEU_Calvin的博客

1.  Bundle

Activity、Service、Receiver都是支持通过Intent传递Bundle数据的,由于Bundle实现了Parcelable接口,所以它可以方便的在不同的进程中传输。因此当我们在一个进程中启动了另外一个进程的Activity、Service、Receiver,我们就可以在Bundle中附加我们需要传输给远程进程的信息(前提是能够被序列化)并通过Intent发送出去。

下面是一个简单的示例,在一个应用中的MainActivity和BundleActivity(分属不同进程)之间使用Bundle传输数据。首先在MainActivity中使用Bundle包装我们的字符串数据。

Bundle bundle = new Bundle();
bundle.putString("ipc", "Bundle test");
Intent intent=new Intent(MainActivity.this,BundleActivity.class);
intent.putExtras(bundle);
startActivity(intent);

并在BundleActivity中进行数据接收,其中“ipc”作为某个Bundle数据单元的标识。

Bundle bundle=getIntent().getExtras();
//获取Bundle的信息
String info=bundle.getString("ipc");

2.  文件

两个进程通过读写同一个文件来交换数据,利用这个思想,我们可以序列化一个对象到文件系统中,同时在另一个进程中反序列化恢复这个对象。共享数据对文件格式没有具体要求,可以是文本文件,也可以是xml文件等等,主要注意处理并发读写的问题。SharePreferences在底层实现上就是采用xml文件来存储键值对,但是SharePreferences的缓存策略使其在内存中会有一份缓存,因此在多进程模式下,系统对它的读写就变得不可靠。因此需要格外注意使用SharePreferences进行IPC。

下面是一个简单的示例,首先定义一个User类,该类必须实现Serializable或者是Parcelable接口,这样便可以序列化。Serializable接口是Java提供的一个序列化接口,使用Serializable非常简单,只要直接User implements Serializable即可,当然也可以在User类中设置serialVersionUID,如下所示。

private static final long serialVersionUID = 519067123721295773L;  

这个serialVersionUID会随着序列化的行为被记录下来,若不设置serialVersionUID,当反序列化时该类若发生变化,如增加或删除了一些成员变量等等(修改类型等是不可以的),这样在校验serialVersionUID时没有找到类中的声明,系统会重新计算该值,那肯定就和以前记录的不一样啦,这样就会反序列化失败。

Parcelable接口在开销上较Serializable接口要小,更适合Android平台,Parcelable接口主要用于内存序列化上,当用于将对象持久化到存储设备或用于网络传输,使用Parcelable会很复杂,这种情况建议使用Serializable接口。

使用Parcelable接口的User类如下所示:

public class User implements Parcelable {
public int userId;
public String userName; public User(int userId, String userName) {
this.userId = userId;
this.userName = userName;
} public int describeContents() {
return 0;
} public void writeToParcel(Parcel out, int flags) {
out.writeInt(userId);
out.writeString(userName);
} public static final Parcelable.Creator<User> CREATOR = new Parcelable.Creator<User>() {
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();
userName = in.readString();
}
}

剩下的就是在一个进程中将该对象序列化到文件中的操作:

User user = new User(1, "SEU_Calvin");
ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream(mFilePath));
objectOutputStream.writeObject(user);

最后在另一个进程中从文件恢复之前存储的User对象的内容,之所以说是内容,是因为反序列化得到的对象只是在内容上和序列化之前的对象是一样的,但他们本质上是两个对象。

User user = null;
ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream(mFilePath));
user = (User) objectInputStream.readObject();

本篇介绍了Android中常见的IPC方式中的Bundle和文件,后面会陆续介绍其他的,如Messenger、AIDL、ContentProvider和Socket等方式。请大家多点赞支持~

Android开发——进程间通信之Bundle和文件的更多相关文章

  1. Android开发——进程间通信之AIDL(二)

    0.  前言 不论是Android还是其它操作系统.都会有自己的IPC机制.所谓IPC(Inter-Process Communication)即进程间通信.首先线程和进程是非常不同的概念,线程是CP ...

  2. Android开发 ---从互联网上下载文件,回调函数,图片压缩、倒转

     Android开发 ---从互联网上下载文件,回调函数,图片压缩.倒转 效果图: 描述: 当点击“下载网络图像”按钮时,系统会将图二中的照片在互联网上找到,并显示在图像框中 注意:这个例子并没有将图 ...

  3. Android开发--UI之Bundle的使用

    Android开发–UI之Bundle的使用 最近,把之前学过的东西大体的整理了以下,并且想把学过的心得分享给大家.我自己做了一个小小的demo,以便说明具体的应用. 这里的两个界面是通过第一个界面输 ...

  4. Android开发——进程间通信之Messenger

    0.  前言 不论是Android还是其他操作系统,都会有自己的IPC机制,所谓IPC(Inter-Process Communication)即进程间通信.首先线程和进程是很不同的概念,线程是CPU ...

  5. Android开发--数据存储之File文件存储

    转载来自:http://blog.csdn.net/ahuier/article/details/10364757,并进行扩充 引言:Android开发中的数据存储方式 Android提供了5种方式存 ...

  6. Android 开发--CMakeList调用本地so文件

    这里写代码片Android开发常常遇到Java调用so文件的情况,本文介绍一下Google最近新推出的应用在android studio中的方法–cmakelist.txt格式调用. so文件分为jn ...

  7. Android开发 ---SQLite数据库,lock文件,结果集游标,适配器,安全退出,给连接设置下划线,编辑器,投影,ContentValues存储,DbHelper,activity栈

    目录截图: 1.activity_main.xml 主界面效果: <?xml version="1.0" encoding="utf-8"?> &l ...

  8. android开发学习---linux下开发环境的搭建&& android基础知识介绍

    一.配置所需开发环境 1.基本环境配置 JDK 5或以上版本(仅有JRE不够) (http://www.oracle.com/technetwork/java/javase/downloads/ind ...

  9. [转载]在Windows下搭建Android开发环境

    http://jingyan.baidu.com/article/bea41d437a41b6b4c51be6c1.html 在Windows下搭建Android开发环境 | 浏览:30780 | 更 ...

随机推荐

  1. css字体更小 css比12px更小的方法

    <span style="margin-top: 0;-webkit-transform-origin-x: 0;-webkit-transform: scale(0.90);&quo ...

  2. springcloud 入门 4 (rebbon源码解读)

    Ribbon: ribbon是springcloud个服务之间调用的一种实现方式:主要提供了客户端的负载均衡.feign集成了Ribbon(下节介绍) 源码分析: 1> 源码入口 @LoadBa ...

  3. Java为什么不支持多继承

    类定义属性和方法 描述某一类事物的抽象 而接口定义的是行为 并不限于任何具体意向 按照逻辑上来说 单继承更明确 一个子类就应该是其父类代表的事物中的某个更具体的类别 不应该即是这种东西又是那种东西 而 ...

  4. SQL语句结合上下文查询(in查询)

    在多个表联合查询时,使用linq语句查询就显得不那么方便了,执行效率也不高, SQL语句查询的优势就显现出来了. using (var context = new YZS_TRAEntities()) ...

  5. Windows2003系统如何设置能让两个人共用一个桌面同时远程控制?

    在windows 2003上,可以两人同时同一桌面控制一台服务器,交流非常方便. 解决方案: 两人都用终端远程登陆到服务器上,其中一人在“开始”--“管理工具”--“终端服务管理器”,选中对方的用户名 ...

  6. 如何从 Windows 虚拟机分离数据磁盘

    当不再需要附加到虚拟机的数据磁盘时,可以轻松地分离它. 这会从虚拟机中删除该磁盘,但不会从存储中删除它. Warning 如果用户分离磁盘,它不会自动删除. 如果订阅了高级存储,则将继续承担该磁盘的存 ...

  7. Azure 中的 Windows 虚拟机概述

    Azure 虚拟机 (VM) 是 Azure 提供的多种可缩放按需分配计算资源之一. 通常情况下,如果需要以更大的力度(相对于其他控制选项)控制计算环境,则应选择 VM. 本文介绍创建 VM 之前的注 ...

  8. MySQL双主.md

    MySQL 双主配置 环境说明 系统 IP 主机名 mysql版本 CentOS 6.8 192.168.197.61 C6-node1 5.6.36 CentOS 6.8 192.168.197.6 ...

  9. ES6标准入门之正则表达式的拓展

    所谓正则表达式,又称规则表达式.(英语:Regular Expression,在代码中常简写为regex.regexp或RE),计算机科学的一个概念.正则表达式通常被用来检索.替换那些符合某个模式(规 ...

  10. Android设置常见控件点击效果

    一. Imageview的点击效果——图片稍微变暗突出点击效果 public class ClickImageView extends AppCompatImageView { public Clic ...