1. 远程调用的数据传输

在远程的函數中,必然会需要传递一些数据,那这些数据是怎么传输的呢?

在IPC中,Proxy端的作用就是将一些参数打包,然后发送出去,下面是在Proxy端经常会遇见的调用远程方法的代码。

可以看到,发送和接收的数据都是通过Parcel來打包的。

 class ActivityManagerProxy implements IActivityManager
{
public int startActivity(IApplicationThread caller, Intent intent,
String resolvedType, IBinder resultTo, String resultWho, int requestCode,
int startFlags, String profileFile,
ParcelFileDescriptor profileFd, Bundle options) throws RemoteException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
data.writeInterfaceToken(IActivityManager.descriptor);
data.writeStrongBinder(caller != null ? caller.asBinder() : null);
intent.writeToParcel(data, 0);
data.writeString(resolvedType);
data.writeStrongBinder(resultTo);
data.writeString(resultWho);
...
mRemote.transact(START_ACTIVITY_TRANSACTION, data, reply, 0);
reply.readException();
int result = reply.readInt();
...
return result;
}
}

一些基本类型,比如String,int可以直接写进Parcel中,那么对于一些比较复杂的数据类型,比如一些自己定义的对象,要怎么写进Parcel里呢?
    
我們通过一个类new一个对象時,这个object的有效范围只是在一个进程里。如果通过IPC机制直接传递一个object是不现实的。因为Java环境里的对象是通过引用來访问的,一个object对其他object,会是通过一个类似指针的引用來访问的,会涉及到类似地址的访问。
所以在传递复杂对象時,必须把object拆解成中间形式,然後在IPC里传输这种中间格式。
那怎么把一个object拆解成中间形式呢?

-->這裏就需要Parcelable接口了

2.Parcelable

当需要在进程间传输一个object時,这个object必須实现Parcelable接口的属性或方法。

例如:
在单进程中,有这样一个类:

 class TaskInfo {
public int mPid;
public int mUid;
public String mPackageName; TaskInfo () {
mPid = -1;
mUid = -1;
mPackageName = null;
}

在实现了Parcelable后,就可以跨进程传输了,定义的TaskInfo类:

 public class TaskInfo implements Parcelable {
public int mPid;
public int mUid;
public String mPackageName; TaskInfo () {
mPid = -1;
mUid = -1;
mPackgeName = null;
}
public int describeContents() { //返回值描述Parcel是起什么作用的,一般是0.
return 0;
} public void writeToParcel(Parcel out, int flags) { //用于发送,把需要传输的属性写入Parcel。
out.writeInt(mPid);
out.writeInf(mUid);
out.writeString(mPackageName);
} public static final Parcelable.Creator<TaskInfo> CREATOR = new Parcelable.Creator<TaskInfo>() {//对应writeToParcel(),接收端process会把Parcel object的中间object回复出來,传递新对象。
public TaskInfo createFromParcel(Parcel in) {//初始化 Parcel object
return new TaskInfo(in);
} public TaskInfo[] newArray(int size) {//用于创建多个空对象,使用默认的初始化方法。
return new TaskInfo[size];
}
};
private TaskInfo(Parcel in) {//使用Parcel的readInt()、readLong()等方法从Parcel里读出來
mPid = in.readInt();
mUid = in.readInt();
mPackageName = in.readString();
}
}

 

3.Parcel的传送

对于Parcel的传输,我们可以比喻成用传真机來发送一个纸盒子到远方。传真机不是時空传送带,并不会真正可以实现某个物品的跨进程传送,但可以变通來完成:

(这部分是从网上看到的,但忘了网址是啥了。。)

这样,传送一个纸盒子就可以分为三个部分了:

1.把纸盒拆解,得到平面化的图形。
2.把平面化的图形通过传真及传到远端。
3.远端的传真机收到平面化的图形后,就可以打印到纸上,再裁剪,粘帖,就可以得到一個一模一样的紙盒子了。

所以,我們在发送時,可以认为是把对象進行拆解打包,然后塞进Parcel对象里。Parcel就相当于是容器,其中会有一段buffer存放中间结果。这个过程会是通过writeToParcel()方法,将对象的属性拆开,填写到Parcel的buffer中。

而读取端,会通过某种方法,將Parcel读取出來。

unflatten操作是通过CREATOR的createFromParcel()來完成。

4.Parcel支持的数据类型

Parcel能支持的數據類型有:
  null
  String
  Byte
  Short
  Integer
  Long
  Float
  Double
  Boolean
  String[]
  boolean[]
  byte[]
  int[]
  long[]
  Object[]
  Bundle
  Map
  Parcelable
  Parcelable[]
  CharSequence
  List
  SparseArray
  IBinder
  Serializable

看,IBinder是可以在进程间传输的!

Binder机制,从Java到C (4. Parcel)的更多相关文章

  1. 从mediaserver入手快速理解binder机制(最简单理解binder)【转】

    本文转载自;https://blog.csdn.net/u010164190/article/details/53015194 Android的binder机制提供一种进程间通信的方法,使一个进程可以 ...

  2. Android系统进程间通信Binder机制在应用程序框架层的Java接口源代码分析

    文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/6642463 在前面几篇文章中,我们详细介绍了A ...

  3. Binder机制,从Java到C (大纲)

    转载请标注:张小燕:http://www.cnblogs.com/zhangxinyan/p/3487381.html 前段时间一直在看有关Binder机制的内容,觉得受益匪浅,整理记录于此,大家请随 ...

  4. Binder机制,从Java到C (1. IPC in Application Remote Service)

    转载请标注:张小燕:http://www.cnblogs.com/zhangxinyan 1. Application 中的 service 我们知道Android中Service有三种类型:Loca ...

  5. Binder机制,从Java到C (5. IBinder对象传递形式)

    1.IBinder的传递 Binder IPC通信中,Binder是通信的媒介,Parcel是通信的內容.远程调用过程中,其参数都被打包成Parcel的形式來传递.IBinder对象当然也不例外,在前 ...

  6. Binder机制,从Java到C (6. Binder in Native : libbinder)

    1.Java和C++中的Binder 从前一篇 Binder机制,从Java到C (5. IBinder对象传递形式) 中可以看到,使用Binder的Java代码,到最后都会进入到Native环境,将 ...

  7. Binder机制,从Java到C (2. IPC in System Service :AMS)

    1.建立Activity和Service的IPC之前 在上一篇 Binder机制,从Java到C (1. IPC in Application Remote Service)  里面有说到Activi ...

  8. Binder机制,从Java到C (3. ServiceManager in Java)

    上一篇 Binder机制,从Java到C (2. IPC in System Service :AMS)  中提到 Application是通过ServiceManager找到了AMS 的servic ...

  9. Binder机制,从Java到C (8. ServiceManager in Native)

    在第三篇 Binder机制,从Java到C (3. ServiceManager in Java) 中,讲到ServiceManager的Stub端在Native,Proxy端在Java.实际上,还要 ...

  10. Binder机制,从Java到C (9. IPC通信过程)

    1.一次IPC通信過程的幾個步驟 一次通信过程简单的说有下面5个步骤,第一眼看上去,肯定不知道什么玩意,多看几遍,慢慢看,其实是能理解的. 1. Client将数据封装成Parcel. (前面已经讲过 ...

随机推荐

  1. unity 编辑器和插件生产(四.2)

    上次 我们告诉编辑器制作,如何将图像加载到现场,如今 我们要告诉下.怎么样 制造UIButton以及UIimage交换. 阿土. 进入专题. 首先,我们要明白 unity机制.button属性等. 首 ...

  2. DevExpress XtraReports 入门四 创建 Web 报表

    原文:DevExpress XtraReports 入门四 创建 Web 报表 本文只是为了帮助初次接触或是需要DevExpress XtraReports报表的人群使用的,为了帮助更多的人不会像我这 ...

  3. SSIS从理论到实战,再到应用(5)----流程控制之Foreach循环

    原文:SSIS从理论到实战,再到应用(5)----流程控制之Foreach循环 上期回顾: SSIS从理论到实战,再到应用(4)----流程控制之For循环 上一期讲了For循环,Foreach循环相 ...

  4. C++ Primer 学习笔记_56_ 类和数据抽象 --消息处理演示示例

    拷贝控制 --消息处理演示样例 说明: 有些类为了做一些工作须要对复制进行控制. 为了给出这种样例,我们将概略定义两个类,这两个类可用于邮件处理应用程序.Message类和 Folder类分别表示电子 ...

  5. 它们的定义ListView,实现Item除去滑动和滑出菜单效果

    这个程序是基于变化从网上开源项目,详情货源忘记.懒得去搜索,.假设有不合适的地方.请与我联系作者.我会及时回复和处理! 序中主要包括两个ListView,一个是实现側滑删除.一个是側滑出菜单,代码中的 ...

  6. Sort函数的相关知识

    sort与stable_sort   需包含头文件:#include <algorithm>因为它是库函数 这两个函数的原理都是快速排序,时间复杂度在所有排序中最低,为O(nlog2n) ...

  7. CSS3新功能简要

    1.CSS3 框架:    由 CSS3,您可以创建圆角.加入到该矩形阴影,使用图片绘制边框.例如 * border-radius -border-*-radius(top,left,right,bo ...

  8. SQL Profile (总结4)--使用演示示例

    前提:sql profile工具的相关视图 dba_sql_profile 10g: sys.sqlprof$attr  &  sqlprof$ 11g: sys.sqlobj$data  & ...

  9. Mobile开发的饕餮盛宴-Zoomla!波CMS2 x2.1正式宣布

    饕餮 [tāo tiè] 古代汉族神话传说中龙的第五子,是一种存在于传说.想象的神奇怪兽. 古书<山海经>介绍其特点是:其形状如羊身人面,其目在腋下,虎齿人爪.其音如婴儿. 作为中国本土软 ...

  10. 【百度地图API】百度API卫星图使用方法和卫星图对比工具

    原文:[百度地图API]百度API卫星图使用方法和卫星图对比工具 百度地图API推出卫星图接口也有一个月啦~ 本文除了介绍如何使用百度地图API来操作卫星图外,还顺带制作了个卫星图对比工具. 一.百度 ...