1. 程式人生 > >Parcelable和Serializable的理解

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>