Android -- Intent傳遞對象的三種方法

當我們使用Intent 在Activity 間傳遞信息時發現putExtra() 方法並不支持自定義對象的傳輸,下面就來介紹三種解決方式。

Serializable 方式

這是最簡單的一種方法,因爲我們要做的就是讓我們自定義的對象實現 Serializable 這個空接口。

public class Person implements Serializable{
        private String mName;
        private String mAddress;

        public String getName() {
            return mName;
     }

     public void setName(String name) {
             mName = name;
     }

        public String getAddress() {
             return mAddress;
        }

        public void setAddress(String address) {
             mAddress = address;
        }
}

這個時候,就已經可以使用Intent 的putExtra() 方法傳遞這個自定義對象了,在Activity 中這樣使用

            Person person = new Person();
            person.setName("Hwaphon");
            person.setAddress("Anhui");

            Intent intent = new Intent(MainActivity.this,SecondActivity.class);
            intent.putExtra("person",person);
            startActivity(intent);
            finish();

在Activity中接收數據

Intent intent = getIntent();
Person person = (Person) intent.getSerializableExtra("person");

使用Serializable方法雖然十分簡單,但是效率卻不容樂觀,因爲它會把整個對象序列化,開銷十分大,爲了追求效率,我們不得不使用另一種方法,也就是Parcelable 方法。

Parcelable 方式

令自定義類實現Parcelable 接口,這個時候必須重寫兩個方法

1.describeContents() : 用於描述內容接口,一般直接 return 0 即可

2.writeToParcel() : 用於將想要傳遞的數據寫入到Parcel 容器中。

除了這兩個方法以外,我們還需要創建一個 Parcelable.Creator 接口的實現,這個接口中也需要我們實現兩個方法

1.createFromParcel() : 用於將寫入Parcel容器中的數據讀出來,用讀出來的數據實例化一個對象,並且返回。

2.newArray() :創建一個長度爲 size 的數組並且返回,一般而言,直接返回return T[size] 即可。

public class Person implements Parcelable{
        private String mName;
        private String mAddress;

        public String getName() {
            return mName;
     }

        public void setName(String name) {
            mName = name;
     }

        public String getAddress() {
             return mAddress;
        }

        public void setAddress(String address) {
            mAddress = address;
        }

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

        @Override
    public void writeToParcel(Parcel parcel, int i) {
            parcel.writeString(mName);
            parcel.writeString(mAddress);
        }

    public static final Parcelable.Creator<Person> CREATOR = new Parcelable.Creator<Person>(){
            @Override
             public Person createFromParcel(Parcel parcel) {
                    Person person = new Person();
                    person.mName = parcel.readString();
                    person.mAddess = parcel.readString();
                    return person;
            }

            @Override
            public Person[] newArray(int i) {
                    return new Person[i];
            }
     };
}

這個時候的接收方法與 Serializable 有點不同,如下

 Intent intent = getIntent();
 Person person = (Person) intent.getParcelableExtra("person");

在writeToParcel() 方法中,我們可以將我們想要的數據寫入容器,如果是我們不需要的數據,那麼我們可以放棄寫入,這也是Parcelabel 方法比 Serializable 方法高效的原因所在。但是,這種方法比Serializable 方法多了太多的實現代碼了,有沒有什麼辦法能改變這一現狀呢?可以使用插件一鍵生成這些代碼,比如說 Android Parcelable code generator 插件,可以直接在Android Studio Plugins 去下載該插件,下載完之後 點擊 Alt+Insert 就可以看到 Parcelable 選項了。

JSON 方式

這個時候自定義對象類爲

public class Person{
        private String mName;
        private String mAdress;

    public String getName() {
            return mName;
        }

        public void setName(String name) {
            mName = name;
        }

        public String getAdress() {
            return mAdress;
     }

        public void setAdress(String adress) {
            mAdress = adress;
        }
    }

使用方式

 //Send
 Intent intent = new Intent(MainActivity.this,SecondActivity.class);

 intent.putExtra("person",new Gson().toJson(person));


// Receive
 Intent intent = getIntent();
 String JsonData = intent.getStringExtra("person");
 Person person = new Gson().fromJson(JsonData,Person.class);

在使用時別忘了導入 Gson 包,否則是無法使用的。

附註:

我已將Gson 和 Parcelable code generator JAR 包上傳到我的百度雲盤,有需要的可以去下載

Parcelable code generator : http://pan.baidu.com/s/1eRmUgLG

GSON : http://pan.baidu.com/s/1nubQw5b

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章