解析Android中的Serializable序列化

jerry Android 2016年03月10日 收藏

1、为何要序列化?

-- 把内存中的java对象能够在磁盘上持久保存

-- 通过网络传输对象

-- 通过RMI(Remote Method Invocation 远程过程调用)传输。

通过序列化可以把对象转化为与平台无关的二进制流,在重新使用前进行反序列化,重新转化为java对象。

(远程过程调用针对分布式Java应用,对开发人员屏蔽不同JVM和网络连接等细节,是的分布在不同JVM上的对象似乎存在于一个统一的JVM中,能够方便的通讯)

2、如何让Java对象可以被序列化?

在java里只需让目标类实现Serializable接口,无须实现任何方法。Serializable接口是一种标记接口,用来标明某个类可以被序列化。

3、如何使用序列化与反序列化?

序列化:使用ObjectOutputStream对象输出流的writeObject()方法,可以把对象写到输出流中。

反序列化:使用ObjectInputStream对象写入流的readObject()方法,并强制转换为已知的目标类即可。

4、对象引用的序列化

如果一个类Person某个成员变量引用了其他类(如class PersonInfo)。即:

  1. class Person implements Serializable{
  2.  
  3. String name;
  4.  
  5. PersonInfo info;
  6.  
  7. }
  8.  

如果想将Person类进行序列化,那么必须要满足:PersonInfo类也能够序列化,即也实现了Serializable接口,

  1. class PersonInfo implements Serializable
  2.  

5、多个对象引用同一个子对象

  1. PersonInfo info = new PersonInfo(“male”,"china");
  2.  
  3. Person xiaomi = new Person("小明",info);
  4.  
  5. Person dabai = new Person("大白",info);
  6.  

如果依次对上面三个对象序列化,原本是下面两个对象都指向上面同一个对象,也就是指存在一个info对象,java为了防止在每个对象序列化时序列化三个info对象,设定了如果多次序列化同一样java对象时,只有在第一次序列化时把这个对象转换为字节序列输出,之后再对它序列化只会指向第一次序列化的编号,而不会再去序列化这个对象。

6、父类序列化

如果父类实现了Serializable接口,则子类自动可序列化,不需要再显示实现该接口。

7、利用Serializable保存自定义数据至本地的例子
MainActivity如下:

  1. package cc.test.serializable;
  2. import java.io.File;
  3. import java.io.FileInputStream;
  4. import java.io.FileOutputStream;
  5. import java.io.IOException;
  6. import java.io.ObjectInputStream;
  7. import java.io.ObjectOutputStream;
  8. import java.util.ArrayList;
  9. import android.app.Activity;
  10. import android.os.Bundle;
  11. import android.os.Environment;
  12. /**
  13. * Demo描述:
  14. * 将ArrayList<自定义数据>在SDCard上进行存取.
  15. *
  16. * Parcelable和Serializable的区别:
  17. * 内存间数据传输时推荐使用Parcelable,如activity间传输数据
  18. * 比如:http://blog.csdn.net/lfdfhl/article/details/10961459
  19. * 保存到本地或者网络传输时推荐使用Serializable
  20. */
  21. public class TestSerializableActivity extends Activity {
  22. @Override
  23. public void onCreate(Bundle savedInstanceState) {
  24. super.onCreate(savedInstanceState);
  25. setContentView(R.layout.main);
  26. testSerializable();
  27. }
  28. private void testSerializable() {
  29. FileOutputStream fileOutputStream=null;
  30. ObjectOutputStream objectOutputStream =null;
  31. FileInputStream fileInputStream = null;
  32. ObjectInputStream objectInputStream = null;
  33. ArrayList<Student> studentsArrayList = new ArrayList<Student>();
  34. Student student = null;
  35. for (int i = 1; i < 5; i++) {
  36. student = new Student(i, "小明" + i);
  37. studentsArrayList.add(student);
  38. }
  39. try {
  40. //存入数据
  41. File file = new File(Environment.getExternalStorageDirectory().toString()
  42. + File.separator +"Test"+File.separator + "data.dat");
  43. if (!file.getParentFile().exists()) {
  44. file.getParentFile().mkdirs();
  45. }
  46. if (!file.exists()) {
  47. file.createNewFile();
  48. }
  49. fileOutputStream= new FileOutputStream(file.toString());
  50. objectOutputStream= new ObjectOutputStream(fileOutputStream);
  51. objectOutputStream.writeObject(studentsArrayList);
  52. //取出数据
  53. fileInputStream = new FileInputStream(file.toString());
  54. objectInputStream = new ObjectInputStream(fileInputStream);
  55. ArrayList<Student> savedArrayList =(ArrayList<Student>) objectInputStream.readObject();
  56. for (int i = 0; i < savedArrayList.size(); i++) {
  57. System.out.println("取出的数据:" + savedArrayList.get(i).toString());
  58. }
  59. } catch (Exception e) {
  60. // TODO: handle exception
  61. }finally{
  62. if (objectOutputStream!=null) {
  63. try {
  64. objectOutputStream.close();
  65. } catch (IOException e) {
  66. e.printStackTrace();
  67. }
  68. }
  69. if (fileOutputStream!=null) {
  70. try {
  71. fileOutputStream.close();
  72. } catch (IOException e) {
  73. e.printStackTrace();
  74. }
  75. }
  76. if (objectInputStream!=null) {
  77. try {
  78. objectInputStream.close();
  79. } catch (IOException e) {
  80. e.printStackTrace();
  81. }
  82. }
  83. if (fileInputStream!=null) {
  84. try {
  85. fileInputStream.close();
  86. } catch (IOException e) {
  87. e.printStackTrace();
  88. }
  89. }
  90. }
  91. }
  92. }

Student如下:

  1. package cc.test.serializable;
  2. import java.io.Serializable;
  3. public class Student implements Serializable {
  4. private Integer id;
  5. private String name;
  6. //注意定义此字段
  7. public static final long serialVersionUID = 9527L;
  8. public Student() {
  9. super();
  10. }
  11. public Student(Integer id, String name) {
  12. super();
  13. this.id = id;
  14. this.name = name;
  15. }
  16. public Integer getId() {
  17. return id;
  18. }
  19. public void setId(Integer id) {
  20. this.id = id;
  21. }
  22. public String getName() {
  23. return name;
  24. }
  25. public void setName(String name) {
  26. this.name = name;
  27. }
  28. @Override
  29. public String toString() {
  30. return "Student [id=" + id + ", name=" + name + "]";
  31. }
  32. }

main.xml如下:

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. android:layout_width="fill_parent"
  4. android:layout_height="fill_parent"
  5. android:orientation="vertical" >
  6. <TextView
  7. android:layout_width="fill_parent"
  8. android:layout_height="wrap_content"
  9. android:text="@string/hello" />
  10. </LinearLayout>