Android中的IPC机制
Android IPC简介
IPC是Inter-Process Communication的缩写,含义就是进程间通信或者跨进程通信,是指两个进程之间进行数据交换的过程。那么什么是进程,什么是线程,进程和线程是两个截然不同的概念。在操作系统中,线程是CPU调度的最小单元,同时线程是一种有限的系统资源。而进程指的一个执行单元,在PC和移动设备上指的是一个程序或者一个应用。一个进程可以包含多个线程,因此进程和线程是包含被包含的关系,最简单情况下,一个进程可以只有一个线程,即主线程,在Android里面也叫UI线程,在UI线程里才能操作界面元素。
那么在Android中,有特色的进程间通信方式就是Binder了,通过Binder可以轻松实现进程间通信。除了Binder,Android还支持Socket,通过Socket也可以实现任意两个终端之间的通信,当然一个设备上的两个进程之间通过Socket通信自然也是可以的。
说到IPC的使用场景就必须提到多进程,只有面对多进程这种场景下,才需要考虑进程间通信。所有运行在不同进程中的四大组件,只要它们之间需要通过内存来共享数据,都会共享失败,这也是多进程所带来的主要影响。正常情况下,四大组件中间不可能不通过一些中间层来共享数据,那么通过简单地指定进程名来开启多进程都会无法正确运行。一般来说,使用多进程会造成如下几方面的问题:
- 静态成员和单例模式完全失效
- 线程同步机制完全失效
- SharedPreferences的可靠性下降
- Application会多次创建
为了解决这个问题,系统提供了很多跨进程通信方法,虽然说不能直接地共享内存,但是通过跨进程通信我们还是可以实现数据交互。实现跨进程通信的方式有很多,比如通过Intent来传递数据,共享文件SharedPreference,基于Binder的Messenger和AIDL以及Socket等。
IPC基础概念介绍
Serializable接口
Serializable是Java提供的一个序列化接口,它是一个空接口,为对象标准的序列化和反序列化操作。使用Serializable来实现序列化相当简单,一句话即可。
public class User implements Serializable {
private static final long seriaVersionUID = 519067123721295773L
}
Parcelable接口
Parcel内部包装了可序列化的数据,可以在Binder中自由传输,在序列化过程中需要实现的功能有序列化、反序列化和内容描述序列化功能有writeToParcel
方法来完成,最终是通过Parcel中的一系列write
方法来完成的。用法如下:
public class MyParcelable implements Parcelable {
// You can include parcel data types
private int mData;
private String mName;
// We can also include child Parcelable objects. Assume MySubParcel is such a Parcelable:
private MySubParcelable mInfo;
// This is where you write the values you want to save to the `Parcel`.
// The `Parcel` class has methods defined to help you save all of your values.
// Note that there are only methods defined for simple values, lists, and other Parcelable objects.
// You may need to make several classes Parcelable to send the data you want.
@Override
public void writeToParcel(Parcel out, int flags) {
out.writeInt(mData);
out.writeString(mName);
out.writeParcelable(mInfo, flags);
}
// Using the `in` variable, we can retrieve the values that
// we originally wrote into the `Parcel`. This constructor is usually
// private so that only the `CREATOR` field can access.
private MyParcelable(Parcel in) {
mData = in.readInt();
mName = in.readString();
mInfo = in.readParcelable(MySubParcelable.class.getClassLoader());
}
public MyParcelable() {
// Normal actions performed by class, since this is still a normal object!
}
// In the vast majority of cases you can simply return 0 for this.
// There are cases where you need to use the constant `CONTENTS_FILE_DESCRIPTOR`
// But this is out of scope of this tutorial
@Override
public int describeContents() {
return 0;
}
// After implementing the `Parcelable` interface, we need to create the
// `Parcelable.Creator<MyParcelable> CREATOR` constant for our class;
// Notice how it has our class specified as its type.
public static final Parcelable.Creator<MyParcelable> CREATOR
= new Parcelable.Creator<MyParcelable>() {
// This simply calls our new constructor (typically private) and
// passes along the unmarshalled `Parcel`, and then returns the new object!
@Override
public MyParcelable createFromParcel(Parcel in) {
return new MyParcelable(in);
}
// We just need to copy this and change the type to match our class.
@Override
public MyParcelable[] newArray(int size) {
return new MyParcelable[size];
}
};
}
Serializable和Parcelable区别
Serializable是Java中的序列化接口,其使用起来简单但是开销很大,在序列化和反序列化过程中需要大量的I/O操作。而Parcelable是Android中的序列化方式,因此更适合用在Android平台上,它的缺点就是使用起来稍微麻烦点,但是它的效率很高。
Binder
直观来说,Binder是Android中的一个类,它实现了IBinder接口。从IPC角度来说,Binder是Android中的一种跨进程通信方式,Binder还可以理解为一种虚拟的物理设备,它的设备驱动是/dev/binder,该通信方式在Linux中没有。从Android Framework角度来说,Binder是ServiceManager连接各种Manager(ActivityManager、WindowManager等等)和相应ManagerService的桥梁。从Android应用层来说,Binder是客户端和服务端进行通信的媒介,当bindService的时候,服务端会返回一个包含了服务端业务调用的Binder对象,通过Binder对象,客户端就可以获取服务端提供的服务或者数据,这里的服务包括普通服务和基于AIDL的服务。
Android中的IPC方式
使用Bundler
我们知道,四大组件中三大组件(activity、service、receiver)都是支持在Intent中传递Bundle数据的,由于Bundle实现了Parcelable接口,所以它可以方便地在不同的进程间传输。
使用文件共享
共享文件也是一种不错的进程间通信方式,两个进程间通过读/写同一个文件来交换数据,比如A进程把数据写入文件,B进程通过读取这个文件来获取数据。
使用Messenger
Messenger可以翻译为信使,顾名思义,通过它可以在不同进程中传递Message对象,在Message中放入我们需要传递的数据,就可以轻松地实现数据的进程间传递。Messenger是一种轻量级的IPC方案,它的底层实现是AIDL,实现Messenger有以下两个步骤,分为服务端进程和客户端进程。
使用AIDL
远程服务跨进程通信的一种方式。
使用ContentProvider
ContentProvider是Android中提供的专门用于不同应用间进行数据共享的方式,它的底层实现同样也是Binder。
使用Socket
Socket也称为“套接字”,是网络通信中的概念,它分为流式套接字和用户数据套接字两种,分别应于网络的传输控制层中的TCP和UDP协议。
选用合适的IPC方式
阅读扩展
源于对掌握的Android开发基础点进行整理,罗列下已经总结的文章,从中可以看到技术积累的过程。
1,Android系统简介
2,ProGuard代码混淆
3,讲讲Handler+Looper+MessageQueue关系
4,Android图片加载库理解
5,谈谈Android运行时权限理解
6,EventBus初理解
7,Android 常见工具类
8,对于Fragment的一些理解
9,Android 四大组件之 " Activity "
10,Android 四大组件之" Service "
11,Android 四大组件之“ BroadcastReceiver "
12,Android 四大组件之" ContentProvider "
13,讲讲 Android 事件拦截机制
14,Android 动画的理解
15,Android 生命周期和启动模式
16,Android IPC 机制
17,View 的事件体系
18,View 的工作原理
19,理解 Window 和 WindowManager
20,Activity 启动过程分析
21,Service 启动过程分析
22,Android 性能优化
23,Android 消息机制
24,Android Bitmap相关
25,Android 线程和线程池
26,Android 中的 Drawable 和动画
27,RecylerView 中的装饰者模式
28,Android 触摸事件机制
29,Android 事件机制应用
30,Cordova 框架的一些理解
31,有关 Android 插件化思考
32,开发人员必备技能——单元测试
Android中的IPC机制的更多相关文章
- Android中的Parcel机制 实现Bundle传递对象
Android中的Parcel机制 实现了Bundle传递对象 使用Bundle传递对象,首先要将其序列化,但是,在Android中要使用这种传递对象的方式需要用到Android Parc ...
- 探索Android中的Parcel机制(上)
一.先从Serialize说起 我们都知道JAVA中的Serialize机制,译成串行化.序列化……,其作用是能将数据对象存入字节流其中,在须要时又一次生成对象.主要应用是利用外部存储设备保存对象状态 ...
- Android中Alarm的机制
本次给大家分析的是Android中Alarm的机制所用源码为最新的Android4.4.4.首先简单介绍如何使用Alarm并给出其工作原理,接着分析Alarm和Timer以及Handler在完成定时任 ...
- Android中的Parcel机制(上)
一.先从Serialize说起 我们都知道JAVA中的Serialize机制,译成串行化.序列化--,其作用是能将数据对象存入字节流当中,在需要时重新生成对象.主要应用是利用外部存储设备保存对象状态, ...
- 浅析Android中的消息机制(转)
原博客地址:http://blog.csdn.net/liuhe688/article/details/6407225 在分析Android消息机制之前,我们先来看一段代码: public class ...
- 浅析Android中的消息机制(转)
在分析Android消息机制之前,我们先来看一段代码: public class MainActivity extends Activity implements View.OnClickListen ...
- 浅析Android中的消息机制-解决:Only the original thread that created a view hierarchy can touch its views.
在分析Android消息机制之前,我们先来看一段代码: public class MainActivity extends Activity implements View.OnClickListen ...
- 浅析Android中的消息机制
在分析Android消息机制之前,我们先来看一段代码: public class MainActivity extends Activity implements View.OnClickListen ...
- 重温Android中的消息机制
引入: 提到Android中的消息机制,大家应该都不陌生,我们在开发中不可避免的要和它打交道.从我们开发的角度来看,Handler是Android消息机制的上层接口.我们在平时的开发中只需要和Hand ...
随机推荐
- linux权限---【600,644,700,755,711,666,777】 - - 博客频道 - CSDN.NET
body { font-family: "Microsoft YaHei UI","Microsoft YaHei",SimSun,"Segoe UI ...
- Ubuntu如何备份和恢复系统 - 落花往事的日志 - 网易博客
在 使用Ubuntu之前,相信很多人都有过使用Windows系统的经历.如果你备份过Windows系统,那么你一定记忆犹新:首先需要找到一个备份工 具(通常都是私有软件),然后重启电脑进入备份工具提供 ...
- 子序列和问题 acm
题目描述 给定一个序列 {a1,a2,…,an},定义从a[l]到a[r]的连续子序列的和为sum[l,r],即sum[l,r]=sigma{ai},l<=i<=r.(1<=l< ...
- 配置 nginx location 实时查看 php-fpm 的状态
在Nginx.conf 里配置 location ~ ^/status$ { include fastcgi_params; fastcgi_pass 127.0.0.1:9000; fastcgi_ ...
- [Cocos2d-x]Lua 资源热更新
什么是热更新 所谓的热更新,指的是客户端的更新. 大致的流程是,客户端在启动后访问更新的URL接口,根据更新接口的反馈,下载更新资源,然后使用新的资源启动客户端,或者直接使用新资源不重启客户端. 热更 ...
- 一种比较简单的在USB U盘中访问nandflash的方法
u8 nandflash_write_buffer[NAND_SERECT_FULL_SIZE]; static int currentBlock = -1; static int currentPa ...
- iOS子线程更新UI的两种方法
http://blog.csdn.net/libaineu2004/article/details/45368427 方法1:performSelectorOnMainThread[self perf ...
- ajax--2017年1月15日
听说点六下就能复制了? ajax: 一般处理程序(数据接口):ashx 跨语言传递数据:xml: 结构不清晰 代码量比较大 查找起来比较费事 非面向对象结构 json: 结构清晰 代码量相对较小 面向 ...
- 《算法导论》插入排序----InsertSort
算法导论,插入排序 public class InsertSort { public static double [] sort(double [] num) { for(int i =1; i< ...
- Tsinsen-1486:树【Trie树 + 点分治】
暴力部分: 这个题一开始的想法是 n^2 枚举两个点,然后logn维护LCA,在倍增的同时维护异或值和 k 的个数. s_z_l老爷指导了新的思路,既然这个树只有n^2个LCA,那么枚举LCA,同时向 ...