1. 程式人生 > >Android開發——通過 Intent 傳遞類物件

Android開發——通過 Intent 傳遞類物件

在android開發中,經常會使用Intent來傳遞資料,在Google官方的android api中對於基本資料型別,Intent類中都有對應的方法 intent.putExtra(key,date);來傳遞資料

然而在實際開發中,基本資料型別肯定是不能夠滿足需要的,這個時候怎麼辦?對於自定義的類物件,如何通過Intent來傳遞呢?

這個時候就需要將物件序列化(Serializable)後才能傳遞,那麼問題來了,

一、什麼是序列化呢?

 通俗的來說就是把一個物件按照順序排列成位元組序列,個人感覺有點類似於網路視訊按照視訊流進行流媒體傳輸的道理,視訊檔案本身佔空間相對較大,不適合網路傳輸,但是如果將視訊按照播放先後順序壓縮成流媒體,一幀幀的傳輸(實際基於TCP/IP協議的網路是分資料包傳輸,每個資料包傳輸數幀,不止一幀),就完全可以傳輸過去了,同樣的道理,Intent是無法傳輸物件的,但是將物件序列化之後就不一樣了。

二、那到底怎麼序列化一個物件?

主要有兩種方法

  • 一種是實現Serializable介面(是JavaSE本身就支援的)
  • 另一種是實現Parcelable介面(是Android特有功能,效率比實現Serializable介面高效,可用於Intent資料傳遞,也可以用於程序間通訊(IPC))

具體操作如下:
1.通過實現Serializable介面將物件序列化
程式碼如下:

public class Person implements Serializable
{
       //這裡定義個serialVersionUID用於進行序列化和反序列化後資料比對
       private
static final long serialVersionUID = -1111L; private String name; private int age; 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; } }

只需要將要傳遞的類物件implements Serializable,然後定義個serialVersionUID常量即可,然後就可以任性的用

intent.putExtra("person",person);

傳遞person物件,這主要是得益於android原始碼中有序列化物件的過載方法,下方該過載方法的android原始碼:

/**
     * Add extended data to the intent.  The name must include a package
     * prefix, for example the app com.android.contacts would use names
     * like "com.android.contacts.ShowAll".
     *
     * @param name The name of the extra data, with package prefix.
     * @param value The Serializable data value.
     *
     * @return Returns the same Intent object, for chaining multiple calls
     * into a single statement.
     *
     * @see #putExtras
     * @see #removeExtra
     * @see #getSerializableExtra(String)
     */
    public Intent putExtra(String name, Serializable value) {
        if (mExtras == null) {
        //從這裡可以看出Intent傳遞資料,其實是用的Bundle(本文作者加的註釋,原始碼沒有這行)
            mExtras = new Bundle();
        }
        mExtras.putSerializable(name, value);
        return this;
    }

2.第二種方法是實現Parcelable介面將物件序列化:

剛剛的Serializable在序列化的時候是將整個物件進行序列化,而Parcelable 方式的實現原理是將一個完整的物件進行分解,而分解後的每一部分都是Intent 所支援的資料型別,這樣也就實現傳遞物件的功能了。

這個相對複雜,先來看看介面定義:

public interface Parcelable 
{
    //內容描述介面,基本不用管
    public int describeContents();
    //寫入介面函式,打包
    public void writeToParcel(Parcel dest, int flags);
    //讀取介面,目的是要從Parcel中構造一個實現了Parcelable的類的例項處理。因為實現類在這裡還是不可知的,所以需要用到模板的方式,繼承類名通過模板引數傳入
    //為了能夠實現模板引數的傳入,這裡定義Creator嵌入介面,內含兩個介面函式分別返回單個和多個繼承類例項
    public interface Creator<T> 
    {
           public T createFromParcel(Parcel source);
           public T[] newArray(int size);
    }
}

只看介面定義可能很暈,下面來看看具體實現步驟:
1. implements Parcelable
2. 重寫writeToParcel方法,將你的物件序列化為一個Parcel物件,即:將類的資料寫入外部提供的Parcel中,打包需要傳遞的資料到Parcel容器儲存,以便從 Parcel容器獲取資料
3. 重寫describeContents方法,內容介面描述,預設返回0就可以
4. 例項化靜態內部物件CREATOR實現介面Parcelable.Creator

public static final Parcelable.Creator<T> CREATOR

注:其中public static final一個都不能少,內部物件CREATOR的名稱也不能改變,必須全部大寫。需重寫本介面中的兩個方法:createFromParcel(Parcel in) 實現從Parcel容器中讀取傳遞資料值,封裝成Parcelable物件返回邏輯層,newArray(int size) 建立一個型別為T,長度為size的陣列,僅一句話即可(return new T[size]),供外部類反序列化本類陣列使用。

簡單說就是通過writeToParcel將你的物件拆解對映成Parcel物件,再通過createFromParcel將Parcel物件組裝對映成你的物件。這個過程很想我剛剛提到的流媒體傳輸,可以將Parcel看成是一個流,通過writeToParcel把物件寫到流裡面,在通過createFromParcel從流裡讀取物件,只不過這個過程需要你來實現,因此寫的順序和讀的順序必須一致。

implements Parcelable實現的person類如下:

public class Person implements Parcelable
{

    private String name;
    private int age;

    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;
    }

    @Override
    public int describeContents()
    {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel out, int flags)
    {
        out.writeString(name);
        out.writeString(age);
    }

    public static final Parcelable.Creator<Person> CREATOR = new Creator<Person>()
    {
        @Override
        public Person[] newArray(int size)
        {
            return new Person[size];
        }

        @Override
        public Person createFromParcel(Parcel in)
        {
            Person person=new Person();  
            person.name=in.readString();
            person.age=in.readInt();
            return person;  
        }
    };

    public Person(Parcel in)
    {
        name= in.readString();
        age= in.readString();
     }
}

三、序列化的作用:

1)永久性儲存物件,儲存物件的位元組序列到本地檔案中;
2)通過序列化物件在網路中傳遞物件;
3)通過序列化在程序間傳遞物件。

 四、兩種方法的比較:

1)在使用記憶體的時候,Parcelable比Serializable效能高,所以推薦使用Parcelable。
2)Serializable在序列化的時候會產生大量的臨時變數,從而引起頻繁的Gabage Collection,導致效能的下降。
3)Parcelable不能使用在要將資料儲存在磁碟上的情況,因為在外界有變化的情況下,Parcelable不能很好的保證資料的持續性。儘管Serializable效率低點,但此時還是建議使用Serializable

相關推薦

Android開發——通過 Intent 傳遞物件

在android開發中,經常會使用Intent來傳遞資料,在Google官方的android api中對於基本資料型別,Intent類中都有對應的方法 intent.putExtra(key,date);來傳遞資料 然而在實際開發中,基本資料型別肯定是不能夠

Android 通過 Intent 傳遞物件

Android中通過 Intent傳遞類物件 1.通過實現Serializable介面傳遞物件(必須實現該介面) 2.通過實現Parcelable介面傳遞物件(必須實現該介面) Bundle.put

AndroidIntent傳遞物件的方法一(Serializable)

Activity之間通過Intent傳遞值,支援基本資料型別和String物件及它們的陣列物件byte、byte[]、char、char[]、boolean、boolean[]、short、short[]、int、int[]、long、long[]、float、

Android開發——使用intent傳遞對象

style 開發 start result oid conda .html cond spa intent傳遞對象有兩種方法: 方式一:Serializable 方式 方式二:Parcelable方式 在這裏不多介紹了,這一篇就是快速上手使用教程,至於詳細原理介紹的,

Android開發使用Intent傳遞複雜資料(List集合,Map等)

Intent(意圖)在Android開發中是用於在各個Activity之間傳輸資料用的。它可傳輸的資料形式主要有以下幾種:1、簡單資料。(使用Bundle即可)2、陣列。3、List集合。4、Map<String, Object>。(可以放在一個List集合裡傳輸

說說如何使用 Android 中的 Intent傳遞物件

使用 Intent 來傳遞物件有兩種方式:Serializable 和 Parcelable。 1 Serializable 方式 假設有一個 POJO 的 Account 類,該類實現了 Serializable 介面: public class Account im

android 利用intent傳遞含有物件的list

 做demo的時候發現要用到intent傳遞一個Object型別的list。方法也很簡單,先將Object類Serializable,然後Intent傳list時強轉成Serializable型別例:i

Android開發筆記之工具使用靜態方法與單例物件方法的優劣

最近在做專案開發的時候用到了很多工具類,之前對工具類的理解僅限於使用靜態方法,沒有細究.寫了很多有損app執行效能的程式碼.例如在靜態方法內建立了例項物件,這樣讓靜態方法持有物件,使得物件一直存在與記憶體中,無法被GC回收,佔用記憶體,影響效能和使用者體驗

Android通過Intent傳遞資料

日常開發中,我們經常遇到通過 Intent 來傳遞資料,預設情況,我們可以看到支援的資料型別: 基本型別:boolean、byte、char 、short、double、float、int、long 字串型別:String、String[]、CharSe

通過Intent傳遞物件,已Map為例

對於物件在Activity中的傳遞我們仍然可以使用Intent來實現,只是要在傳遞之前需要將Map強制轉化為Serialzable型別(對於自定義的類我們也可以讓其實現Serializable介面)來實現。 private Map<String, String>

android開發學習 ------- RecyclerView多型實例

靜態 mco gho add ren dom ble notify 布局 實現RecyclerView多類型的實例:效果如下圖所示 public class CarFragment extends Fragment{ private View view;

動態載入Dll時,通過Type生成物件

原文: 動態載入Dll時,通過Type生成類物件 轉:http://www.cnblogs.com/zfanlong1314/p/4197383.html “反射”其實就是利用程式集的元資料資訊。 反射可以有很多方法,編寫程式時請先匯入 System.Reflection 名稱空間。

Android開發通過adapter顯示listview

首先,定義一個adapter繼承於某個ArrayAdapter,例項化adapter時將要顯示的peers傳遞進去,然後通過listview.setadapter(new adapter)顯示, getview()方法決定每個item包含的資訊與顯示 adapter = new WiF

Activity中通過Intent傳遞HashMap集合

對於物件在Activity中的傳遞我們仍然可以使用Intent來實現,只是要在傳遞之前需要將Map強制轉化為Serialzable型別(對於自定義的類我們也可以讓其實現Serializable介面)來實

Android開發中資料傳遞大集合

眾所周知,Android開發中資料傳遞方式多種多樣,根據不同的用途需要選擇不同的傳遞方式。作為剛接觸Android才一年的freshman來說,第一次寫部落格還是有點緊張的,嘿嘿。好咯,言歸正傳,進入正題。 據我目前瞭解,資料傳遞方式有 (1)最基本的

[Android開發] Json解析工具,一個搞定Json的解析

一、簡介 利用遞迴的方式反射解析到bean裡面 二、詳細程式碼 1、 Json格式 例如伺服器指定規定json格式為: { "code": "……" , // 返回代號,預留欄位,預設返回null "type":"ER

Android開發學習之TypedArray

     在學習Android的開發中,學習Gallery檢視顯示圖片的過程中,在設定圖片介面卡的時候,用到了此TypedArray型別,這次根據android SDK,一塊把此型別弄清楚!      android.content.res.TypedArray     

Android 最全 Intent 傳遞資料姿勢

點選上面藍色字型關注“IT大飛說” 置頂公眾號(ID:ITBigFly)第一時間收到推送 作為一個 Android 開發人員,我們都是用過 Intent,用它來在元件之間傳遞資料,所以說 Intent 是元件之間通訊的使者,一般情況下,我們傳遞的都

Android開發實現HttpClient工具以及HttpClient的3種超時說明

引子 在Android開發中我們經常會用到網路連線功能與伺服器進行資料的互動,為此Android的SDK提供了Apache的HttpClient來方便我們使用各種Http服務。你可以把HttpClient想象成一個瀏覽器,通過它的API我們可以很方便的發出GET,POST請求(當然它的功能遠不止這些)。

Android開發 通過JNI實現JAVA與C/C++程式間的呼叫和回撥

       在一些Android應用的開發中,需要通過JNI和 Android NDK工具實現JAVA和C/C++之間的相互呼叫。        Java Native Interface (JNI)標準是java平臺的一部分,它允許Java程式碼和其他語言寫的程式碼進行