Android通過Intent傳遞資料
日常開發中,我們經常遇到通過 Intent 來傳遞資料,預設情況,我們可以看到支援的資料型別:
基本型別:boolean、byte、char 、short、double、float、int、long
字串型別:String、String[]、CharSequence、CharSequence[]
序列化型別:Serializable、Parcelable
其他型別:八種基本型別的陣列、IntegerArray、StringArray、CharSequenceArray、ParcelableArray
基本型別我們比較好理解,接下來我們做簡要分析。
當然,如果你使用Bundle也是一樣的。
對於基本型別我們可以不做任何處理即可在Activity或者Service中傳遞。那麼對於自定義型別,我們怎麼做呢?
何謂序列化
當我們需要對JVM中的java物件進行轉儲時,就需要將其轉化成二進位制序列,然後才能儲存到外部。這個序列中儲存了java物件的型別,資料,資料型別等。當需要的時候,再對儲存的二進位制序列進行反序列化,即可將其還原。常見的場景比如:儲存JVM中物件,通過Socket傳遞java物件,RMI等等。
String型別
為什麼把這個放在第一位呢?
原因很簡單:簡單
基本型別不用說,直接傳遞即可,對於我們的自定義型別,如果你跟我一樣,不太喜歡(熟悉 T-T)Serializable和Parcelable,那用String型別最簡單了。其實這個說法還有個前提,就是我們的專案中需要整合json工具(不過至少有gson)。使用方法如下:首先通過json工具將我們的Object轉換成json字串,然後在接收處在通過json工具還原為Object。
從效率來看,會比下面兩種情況低。但是對初學者來說,會比下面兩種用起來簡單。目前還沒有遇到出錯的問題(可能時因為我傳遞的資料比較小比較簡單吧)。
Serializable
Java中經常會遇到 Serializable,比如這樣:
public class Person implements Serializable {
public String name;
public int age;
public boolean login;
public float score;
}
有些地方需要進行序列化時,IDE會提示我們實現一個介面:Serializable
private static final long serialVersionUID = 23333333333333333333L;
)。如果你沒有去追究為什麼,那麼事情就此結束。通過Intent傳遞資料時,也是如此。好了,我們進入下一部分~~
哈哈,哪能這麼簡單。你可能會問,為什麼加個這個介面即可?Serializable是一種 標記介面,當我們實現這個介面之後,系統會自動通過反射機制將我們物件的成員進行序列化。這裡會涉及一些其他資訊,比如:serialVersionUID、靜態常量的序列化等等,更多資訊請參考這裡。
Parcelable
Parcelable是android特有的處理序列化的方法。先看簡單的使用:
建立一個類:
public class User implements Parcelable { public String userName; public int age; public boolean login; public float score; }
使用AndroidStudio的程式碼生成功能生成如下 模版 程式碼:
public class User implements Parcelable { public String userName; public int age; public boolean login; public float score; protected User(Parcel in) { userName = in.readString(); age = in.readInt(); login = in.readByte() != 0; score = in.readFloat(); } @Override public void writeToParcel(Parcel dest, int flags) { dest.writeString(userName); dest.writeInt(age); dest.writeByte((byte) (login ? 1 : 0)); dest.writeFloat(score); } @Override public int describeContents() { return 0; } public static final Creator<User> CREATOR = new Creator<User>() { @Override public User createFromParcel(Parcel in) { return new User(in); } @Override public User[] newArray(int size) { return new User[size]; } }; }
對比上面的兩段程式碼,我們可以發現:
構造方法中接收一個 Parcel 物件,通過這個物件對成員變數賦值
實現了
Parcelable
介面的方法- 在
writeToParcel
方法中將我們的成員變數寫入Parcel
在
describeContents
中返回一個數字 0Describe the kinds of special objects contained in this Parcelable instance’s marshaled representation. For example, if the object will include a file descriptor in the output of writeToParcel(Parcel, int), the return value of this method must include the CONTENTS_FILE_DESCRIPTOR bit.
- 在
建立了一個
public static final
常量CREATOR
這樣我們就可以通過Intent傳遞物件了。
在android的很多文章中都可以看到,Intent中傳遞資料,強烈推薦使用 Parcelable
他的效率會比 Serializable
更高(比如後者沒有使用反射等等)。當然沒有完美的事情,Parcelable
並不能完全取代Serializable
,比如將JVM物件儲存到磁碟等等。但是對於Android開發中的通過Intent傳遞資料來說,已經足夠。