因为bundle传递数据时只支持基本数据类型,所以在传递对象时需要序列化转换成可存储或可传输的本质状态(字节流)。序列化后的对象可以在网络、IPC(比如启动另一个进程的Activity、Service和Reciver)之间进行传输,也可以存储到本地。
Serializable 是序列化的意思,表示将一个对象转换成存储或可传输的状态。序列化后的对象可以在网络上进传输,也可以存储到本地。
除了Serializable之外,使用Parcelable也可以实现相同的效果,不过不同于将对象进行序列化,Parcelable方式的实现原理是将一个完整的对象进行分解,而分解后的每一部分都是Intent所支持的数据类型,这也就实现传递对象的功能了。
区别总结如下图所示:
JSON的全称是JavaScript Object Notation,也就是JavaScript 对象表示法 JSON是存储和交换文本信息的语法,类似XML,但是比XML更小、更快,更易解析 JSON是轻量级的文本数据交换格式,独立于语言,具有可描述性,更易理解,对象可以包含多个名称/值对,比如:
{"name":"zhangsan" , "age":25}
<span class="copy-code-btn">复制代码</span>
使用谷歌的GSON包进行解析,在 Android Studio 里引入依赖:
compile 'com.google.code.gson:gson:2.7'
<span class="copy-code-btn">复制代码</span>
值得注意的是实体类中变量名称必须和json中的值名字相同。
1、解析成实体类:
Gson gson = new Gson();
Student student = gson.fromJson(json1, Student.class);
<span class="copy-code-btn">复制代码</span>
2、解析成int数组:
Gson gson = new Gson();
int[] ages = gson.fromJson(json2, int[].class);
<span class="copy-code-btn">复制代码</span>
3、直接解析成List.
Gson gson = new Gson();
List<integer> ages = gson.fromJson(json2, newTypeToken<list<integer>>(){}.getType);
Gson gson = new Gson();
List<student> students = gson.fromJson(json3, newTypeToke<list<student>>(){}.getType);
<span class="copy-code-btn">复制代码</span></list<student></student></list<integer></integer>
- 轻量级的数据交换格式
- 读写更加容易
- 易于机器的解析和生成
- 语义性较差,不如 xml 直观
优点:
1.XML树在内存中完整存储,因此可以直接修改其数据结构.
2.可以通过该解析器随时访问XML树中的任何一个节点.
3.DOM解析器的API在使用上也相对比较简单.
缺点:
如果XML文档体积比较大时,将文档读入内存是非消耗系统资源的.
使用场景:
- DOM 是与平台和语言无关的方式表示 XML文档的官方 W3C 标准.
- DOM 是以层次结构组织的节点的集合.这个层次结构允许开人员在树中寻找特定信息.分析该结构通常需要加载整个文档和构造层次结构,然后才能进行任何工作.
- DOM 是基于对象层次结构的.
优点:
SAX 对内存的要求比较低,因为它让开发人员自己来决定所要处理的标签.特别是当开发人员只需要处理文档中包含的部分数据时,SAX 这种扩展能力得到了更好的体现.
缺点:
用SAX方式进行XML解析时,需要顺序执行,所以很难访问同一文档中的不同数据.此外,在基于该方式的解析编码程序也相对复杂.
使用场景:
对于含有数据量十分巨大,而又不用对文档的所有数据行遍历或者分析的时候,使用该方法十分有效.该方法不将整个文档读入内存,而只需读取到程序所需的文档标记处即可.
android SDK提供了xmlpullapi,xmlpull和sax类似,是基于流(stream)操作文件,后者根据节点事件回调开发者编写的处理程序.因为是基于流的处理,因此xmlpull和sax都比较节约内存资源,不会像dom那样要把所有节点以对象树的形式展现在内存中.xmpull比sax更简明,而且不需要扫描完整个流.
1). 实现序列化 Serializable
2). 属性私有化,并提供get,set方法
3). 提供无参构造
4). 属性名必须与json串中属性名保持一致 (因为Gson解析json串底层用到了Java的反射原理)
1,SDK提供JSONArray,JSONObject
2,google提供的 Gson 通过fromJson()实现对象的反序列化(即将json串转换为对象类型) 通过toJson()实现对象的序列化 (即将对象类型转换为json串)
####6. JSON的结构?
json是一种轻量级的数据交换格式, json简单说就是对象和数组,所以这两种结构就是对象和数组两种结构,通过这两种结构可以表示各种复杂的结构
1、对象:对象表示为"{}"扩起来的内容,数据结构为 {key:value,key:value,...}的键值对的结构,在面向对象的语言中,key为对象的属性,value为对应的属性值,所以很容易理解,取值方法为 对象.key 获取属性值,这个属性值的类型可以是 数字、字符串、数组、对象几种。
2、数组:数组在json中是中括号"[]"扩起来的内容,数据结构为 ["java","javascript","vb",...],取值方式和所有语言中一样,使用索引获取,字段值的类型可以是 数字、字符串、数组、对象几种。 经过对象、数组2种结构就可以组合成复杂的数据结构了。
可以肯定的是,两者都是支持序列化和反序列化的操作。
两者最大的区别在于 存储媒介的不同,Serializable 使用 I/O 读写存储在硬盘上,而 Parcelable 是直接 在内存中读写。很明显,内存的读写速度通常大于 IO 读写,所以在 Android 中传递数据优先选择 Parcelable。
Serializable 会使用反射,序列化和反序列化过程需要大量 I/O 操作, Parcelable 自已实现封送和解封(marshalled &unmarshalled)操作不需要用反射,数据也存放在 Native 内存中,效率要快很多。
使用Parcelable插件(Android Parcelable code generator)进行实体类的序列化的实现。
序列化,表示将一个对象转换成可存储或可传输的状态。序列化的原因基本三种情况:
1.永久性保存对象,保存对象的字节序列到本地文件中;
2.对象在网络中传递;
3.对象在IPC间传递。
对明确指出了目标组件名称的Intent,我们称之为"显式Intent"。
对于没有明确指出目标组件名称的Intent,则称之为"隐式 Intent"。
对于隐式意图,在定义Activity时,指定一个intent-filter,当一个隐式意图对象被一个意图过滤器进行匹配时,将有三个方面会被参考到:
动作(Action)
类别(Category ['kætɪg(ə)rɪ] )
数据(Data )
<activity android:name=".MainActivity" android:label="@string/app_name">
<intent-filter>
<action android:name="com.wpc.test">
<category android:name="android.intent.category.DEFAULT">
<data android:mimetype="image/gif">
</data></category></action></intent-filter>
</activity>
####11. Intent的使用方法,可以传递哪些数据类型。
通过查询Intent/Bundle的API文档,我们可以获知,Intent/Bundle支持传递基本类型的数据和基本类型的数组数据,以及String/CharSequence类型的数据和String/CharSequence类型的数组数据。而对于其它类型的数据貌似无能为力,其实不然,我们可以在Intent/Bundle的API中看到Intent/Bundle还可以传递Parcelable(包裹化,邮包)和Serializable(序列化)类型的数据,以及它们的数组/列表数据。
所以要让非基本类型和非String/CharSequence类型的数据通过Intent/Bundle来进行传输,我们就需要在数据类型中实现Parcelable接口或是Serializable接口。
http://blog.csdn.net/kkk0526/article/details/7214247
####12. Parcel 类详解,Parcel 和 Parcelable 的区别?
【参考】:Parcel 在英文中有两个意思,其一是名词,为包裹,小包的意思; 其二为动词,
意为打包,扎包。邮寄快递中的包裹也用的是这个词。Android 采用这个词来表示封装消息
数据。这个是通过 IBinder 通信的消息的载 体。需要明确的是 Parcel 用来存放数据的是内
存(RAM),而不是永久性介质(Nand 等)。
Parcelable,定义了将数据写入 Parcel,和从 Parcel 中读出的接口。一个实体(用类来表示),
如果需要封装到消息中去,就必须实现这一接口,实现了这一接口,该实体就成为“可打包
的”了。Parcel 翻译过来就是打包的意思,其实就是包装了我们需要传输的数据,然后在 Binder 中
传输,用于跨进程传输数据。
Parcel 提供了一套机制,可以将序列化之后的数据写入一个共享内存中,其他进程通过 Parcel
可以从这块共享内存读出字节流,并反序列化成对象
Parcel 是一个存放读取数据的容器,系统中的 binder 进程间通信(IPC)就使用了 Parcel 类来
进行客户端与服务端数据交互,而且 AIDL 的数据也是通过 Parcel 来交互的。在 Java 层和
C++层都实现了 Parcel,由于它在 C/C++中,直接使用了内存来读取数据,因此,它更有效
率。