Parcelable和Serializable的理解
很少在部落格上敲文字了,都是直接上程式碼就結束了,今天抽點時間寫點東西。
我們知道在一般情況下,在兩個或者多個Activity中傳遞資料中通過Intent的函式只能傳遞基本資料型別,那當我們想傳輸複雜的類的資料型別時候,我們就必須用到Parcelable或者Serializable介面經行傳遞資料。
Parcelable和Serializable都是能對資料經行序列化,將資料轉化成位元組流的方式進行傳輸,當這些位元組流傳輸完畢後再對其進行反序列化,達到傳輸複雜資料的目的。
Serializable介面是原先Java Se中就存在的Api,但是在google公司在Android中又添加了Parcelable介面,為什麼呢?第一,Parcelable比Serializable的傳輸速率要快很多倍,大概十倍左右(具體不知道),所以實現Parcelable介面可能提高程式的效能。第二,Parcelable可以進行IPC通訊,即跨程序通訊,這是Serializable做不到的。還有一些優點大家可以摸索,我就不累述了。
不說了,上程式碼
package com.example.administrator.test;
import android.os.Parcel;
import android.os.Parcelable;
/**
* Created by hd on 2015/12/16.
*/
public class Student implements Parcelable {
private String name;
private int age;
private String address;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this .address = address;
}
public static final Creator<Student> CREATOR = new Creator<Student>() {
@Override
public Student createFromParcel(Parcel in) {
Student a = new Student();
a.setName(in.readString());
a.setAddress(in.readString());
a.setAge(in.readInt());
return a;
}
@Override
public Student[] newArray(int size) {
return new Student[0];
}
};
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(name);
dest.writeString(address);
dest.writeInt(age);
}
@Override
public String toString() {
return "name:" + name + "\n" +
"address:" + address + "\n" +
"age:" + age;
}
}
可以看到,在這個bean中我實現了Parcelable介面,我們需要實現一些介面中的方法:
public int describeContents();
對介面的描述,可以直接return 0;
public void writeToParcel(Parcel dest, int flags);
這個方法提供一個Parcel物件,在傳遞中就是通過將資料儲存在這個物件中進行傳遞,所以我們要對這個Parcel進行寫入資料的操作。至於flag引數只是作為一個標記,你可以在新增在資料中傳遞。
/**
* 此介面必須被實現,並且需要寫成public許可權以及物件名為CREATOR(必須大寫)
*/
public interface Creator<T> {
public T createFromParcel(Parcel source);
public T[] newArray(int size);
}
這是一個Parcelable內部的一個介面, 其中createFromParcel就是從Parcel中反序列化資料。
注意:
// 1.必須實現Parcelable.Creator介面,否則在獲取Person資料的時候,會報錯,如下:
// android.os.BadParcelableException:
// Parcelable protocol requires a Parcelable.Creator object called CREATOR on class com.um.demo.Person
// 2.這個介面實現了從Percel容器讀取Person資料,並返回Person物件給邏輯層使用
// 3.實現Parcelable.Creator介面物件名必須為CREATOR,不如同樣會報錯上面所提到的錯;
// 4.在讀取Parcel容器裡的資料事,必須按成員變數宣告的順序讀取資料,不然會出現獲取資料出錯
// 5.反序列化物件
package com.example.administrator.test;
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
public class MainActivity extends AppCompatActivity {
private Button btnSend;
private Button btnSeriaSend;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btnSend = (Button) findViewById(R.id.btnSend);
btnSend.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent();
Student a = new Student();
a.setName("小明");
a.setAddress("福建");
a.setAge(25);
intent.setFlags(0);
intent.setClass(MainActivity.this, SecondActivity.class);
intent.putExtra("hd", a);
startActivity(intent);
}
});
btnSeriaSend = (Button) findViewById(R.id.btnSeriaSend);
btnSeriaSend.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent();
Teacher t = new Teacher();
intent.setFlags(1);
t.setName("小紅");
t.setAddress("浙江");
t.setAge(24);
intent.putExtra("hd", t);
intent.setClass(MainActivity.this, SecondActivity.class);
startActivity(intent);
}
});
}
}
package com.example.administrator.test;
import java.io.Serializable;
/**
* Created by hd on 2015/12/16.
*/
public class Teacher implements Serializable {
private String name;
private String address;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "name:" + name + "\n" +
"address:" + address + "\n" +
"age:" + age;
}
}
這是Serializable的序列化,很簡單,直接實現介面就行,但是不推薦噢。
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.example.administrator.test.MainActivity">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/tvTest"/>
</RelativeLayout>