iT邦幫忙

2017 iT 邦幫忙鐵人賽
DAY 27
0
自我挑戰組

Android初學筆記系列 第 27

Day 27 - Parcelable物件

  • 分享至 

  • twitterImage
  •  

今天補充一個之前忘記講的東西,當我們要將物件傳遞到下一個Activity時,用以往傳遞字串的Intent或Bundle方式都會報錯,因為物件必須序列化後才可以傳遞。

將物件序列化的方式有兩種,一是Java原生的Serializable,二是Android特有的Parcelable,而Parcelable的處理速度較快,且處理時不會產生大量暫時變數讓系統一直GC,在傳遞大量資料時會有較好的效能表現。

序列化物件

以Day24的Albums物件為例,原本長這樣

public class Albums {

    private int userId;
    private int id;
    private String title;

    public Albums(int userId, int id, String title) {
        this.userId = userId;
        this.id = id;
        this.title = title;
    }

    public int getUserId() {
        return userId;
    }

    public int getId() {
        return id;
    }

    public String getTitle() {
        return title;
    }
}

轉換成Parcelable時要讓物件implements Parcelable並實作幾個方法,建議implements之後當Android Studio報錯時點紅色燈泡使其自動完成

public class Albums implements Parcelable {

    private int userId;
    private int id;
    private String title;

    public Albums(int userId, int id, String title) {
        this.userId = userId;
        this.id = id;
        this.title = title;
    }

    public int getUserId() {
        return userId;
    }

    public int getId() {
        return id;
    }

    public String getTitle() {
        return title;
    }
    /* 以上都跟原來一樣 */

    /* 以下為新增的Parcelable部分 */
    // 讀取參數,參數順序要和建構子一樣
    protected Albums(Parcel in) {
        userId = in.readInt();
        id = in.readInt();
        title = in.readString();
    }

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

    // 寫入參數,參數順序要和建構子一樣
    @Override
    public void writeToParcel(Parcel parcel, int i) {
        parcel.writeInt(userId);
        parcel.writeInt(id);
        parcel.writeString(title);
    }

    public static final Creator<Albums> CREATOR = new Creator<Albums>() {
        @Override
        public Albums createFromParcel(Parcel in) {
            return new Albums(in);
        }

        @Override
        public Albums[] newArray(int size) {
            return new Albums[size];
        }
    };
}

大部分情況describeContents()和CREATOR都不用改,只要記得每次新增變數時除了在建構子新增之外,也要在protected Albums和writeToParcel中增加就好了。


傳遞物件

完成以上部分之後就可以用Intent或Bundle傳遞物件

// 建立物件方式跟原本相同
Albums albums = new Albums(1, 1, "Castle on the Hill");
// 直接將物件交給Intent傳遞
Intent intent = new Intent(MainActivity.this, SecondActivity.class);
intent.putExtra("albums", albums);
startActivity(intent);

使用getParcelableExtra接收物件

// 接收物件
Intent intent = getIntent();
Albums albums = intent.getParcelableExtra("albums");

也可以傳遞裝著物件的ArrayList

// 建立物件
Albums albums = new Albums(1, 1, "Castle on the Hill");
// 建立ArrayList放物件
ArrayList<Albums> list = new ArrayList<>();
list.add(albums);
// 使用putParcelableArrayListExtra傳遞
Intent intent = new Intent(MainActivity.this, SecondActivity.class);
intent.putParcelableArrayListExtra("albums list", list);
startActivity(intent);

接收時使用getParcelableArrayListExtra

// 接收物件List
Intent intent = getIntent();
ArrayList<Albums> list = intent.getParcelableArrayListExtra("albums list");

Parcelable的建立比較麻煩一點點,之後可以用parcelabler網站輔助,貼上物件程式碼後自動生成Parcelable程式碼,就可以無痛轉成Parcelable啦。


上一篇
Day 26 - BroadcastReceiver接收事件
下一篇
Day 28 - Notification通知
系列文
Android初學筆記30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言