[Android] Android 最全 Intent 傳遞數據姿勢
我們都是用過 Intent,用它來在組件之間傳遞數據,所以說 Intent 是組件之間通信的使者,一般情況下,我們傳遞的都是一些比較簡單的數據,並且都是基本的數據類型,寫法也比較簡單,今天我在這裏說的是如何使用 Intent 傳遞對象及集合,我們知道Intent 是不能直接傳遞沒有序列化的對象的,說到序列化,我們都知道,序列化有兩種方式,即實現 Sereriable 或者 Paracelable 接口。默認情況下,像 List、Bitmap 等默認幫我們已經實現了序列化,我們就可以直接進行傳遞,還有一些像 Map 集合,自定義的 class,默認是沒有實現序列化的接口的,我們必須要先實現序列化才可以進行傳遞。
1.傳遞序列化對象
1.1 方式一
這種方式比較簡單,我們可以先將對象使用 Gson 先序列化成 Json 字符串,然後作為字符串來使用 Intent,這種方式的好處是不需要實現 Sereriable 或者 Paracelable,壞處就是需要額外的使用 Gson 來序列化和解析。
代碼示例:
ActivityA 中設置數據:
User user = new User(); user.setName("Jack"); user.setAge(18); Intent intent = new Intent(ActivityA.this, ActivityB.class); intent.putExtra("user", new Gson().toJson(user)); startActivity(intent);
ActivityB 中獲取數據:
String json = getIntent().getStringExtra("user"); User user = new Gson().fromJson(json, User.class);
1.2 方式二
這種方式就是將數據封裝到 Bundle 中然後把 Bundle 對象調用 Intent 的 putExtra 方法然後傳遞過去,Bundle 類默認也是已經實現了 Parcelable 接口的,所以可以傳遞 Bundle 對象。
代碼示例:
ActivityA 中設置數據:
// 創建一個Bundle對象封裝數據 Bundle data = new Bundle(); data.putInt("age", 18); data.putString("name", "Jack"); intent.putExtra("data", data);
ActivityB 中獲取數據:
Bundle data = getIntent().getBundleExtra("data"); int id = data.getInt("age"); String name = data.getString("name");
1.3 方式三
傳遞實現了 Serializable 接口的對象,這種方式也比較簡單,傳遞之前先實現 Serializable 接口,也不需要重寫方法。
代碼示例:
ActivityA 中設置數據:
User user = new User(); user.setName("Jack"); user.setAge(18); Intent intent = new Intent(ActivityA.this, ActivityB.class); Bundle bundle = new Bundle(); bundle.putSerializable("user", user); intent.putExtras(bundle); startActivity(intent);
ActivityB 中獲取數據:
Intent intent = getIntent(); User user = (User)intent.getSerializableExtra("user");
1.4 方式四
傳遞實現了 Parcelable 接口的對象,這種方式比實現 Serializable 接口的方式稍微麻煩一點,需要重寫方法,不過我們程序員都是比較懶的,給大家推薦一個插件: android-parcelable-intellij-plugin ,安裝完之後就可以使用快捷鍵自動生成實現了 Serializable 接口的對象了,是不是比較方便。
實現 Serializable 對象的 User 類示例代碼如下:
public class User 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 dest, int flags) { dest.writeString(this.name); dest.writeInt(this.age); } public User() { } protected User(Parcel in) { this.name = in.readString(); this.age = in.readInt(); } public static final Parcelable.Creator<User> CREATOR = new Parcelable.Creator<User>() { @Override public User createFromParcel(Parcel source) { return new User(source); } @Override public User[] newArray(int size) { return new User[size]; } }; }
傳遞數據的方法和 Serializable 類似
代碼示例:
ActivityA 中設置數據:
User user = new User(); user.setName("Jack"); user.setAge(18); Intent intent = new Intent(ActivityA.this, ActivityB.class); Bundle bundle = new Bundle(); bundle.putParcelable("user", user); intent.putExtras(bundle); startActivity(intent);
ActivityB 中獲取數據:
Intent intent = getIntent(); User user = (User)intent.getParcelableExtra("user");
2.傳遞集合類
2.1 傳遞 List 集合數據
如果我們要傳遞的 List 集合,我們可以把 List 強轉成 Serializable 類型,List 默認是實現了 Serializable 接口的,但是註意 List 的泛型類也必須要實現了 Serializable 接口,基本類型及包裝類就不用了。
代碼示例:
ActivityA 中設置數據:
User user1 = new User(); user1.setName("Jack"); user1.setAge(18); User user2 = new User(); user2.setName("Marry"); user2.setAge(20); List<User> list = new ArrayList<>(); list.add(user1); list.add(user2); Intent intent = new Intent(ActivityA.this, ActivityB.class); intent.putExtras("list", (Serializable) list); startActivity(intent);
ActivityB 中獲取數據:
Intent intent = getIntent(); List<User> list = (List<User>) getIntent().getSerializableExtra("list");
2.2 傳遞 Map 集合數據
Map接口及他的實現類默認是沒有實現序列化的接口的,我們要想傳遞 Map 就要讓 Map 實現序列化接口,我們可以自定義一個類,以HashMap為例吧,我們的類就叫 SerializableHashMap 吧,然後讓定義一個 Map 變量作為成員屬性並實現序列化接口,這樣我們的類就可以進行傳遞了,SerializableHashMap 的實現如下:
public class SerializableHashMap implements Serializable { private HashMap<String, String> map; public SerializableHashMap() { } public SerializableHashMap(HashMap<String, String> map) { this.map = map; } public HashMap<String, String> getMap() { return map; } public void setMap(HashMap<String, String> map) { this.map = map; } }
代碼示例:
ActivityA 中設置數據:
HashMap<String, Object> map = new HashMap<>(); map.put("name", "Jack"); map.put("age", 18); SerializableHashMap sMap = new SerializableHashMap(); sMap.setMap(map); // 將map數據添加到封裝的sMap中 Bundle bundle = new Bundle(); bundle.putSerializable("map", sMap); Intent intent = new Intent(ActivityA.this, ActivityB.class); intent.putExtras(bundle); startActivity(intent);
ActivityB 中獲取數據:
Intent intent = getIntent(); Bundle bundle = intent.getExtras(); SerializableHashMap sMap = (SerializableHashMap) bundle.get("map"); HashMap<String, Object> map = sMap.getMap();
2.3 如何選擇?
另外,默認 Intent 幫我們實現了,可以支持傳遞 String 數組等,也比較簡單,這裏就不贅述了,另外如果數據量比較大的情況下,建議使用第三方框架來進行傳遞數據,例如:EventBus 等來代替,這樣的話可以避免造成 TransactionTooLargeException。
如何選擇哪種序列化方式?弄清楚他們的區別,你也就知道使用哪個更合適了。
Serializable 和 Parcelable 接口的區別:
在使用內存的時候,Parcelable 比 Serializable 性能高,所以推薦使用 Parcelable;
Serializable 在序列化的時候會產生大量的臨時變量,從而引起頻繁的 GC;
Parcelable 不能使用在要將數據存儲在磁盤上的情況,因為 Parcelable 不能很好的保證數據的 持續性,在外界有變化的情況下,盡管 Serializable 效率低點,但此時還是建議使用Serializable;
本博客地址: wukong1688
本文原文地址:https://www.cnblogs.com/wukong1688/p/10767673.html
轉載請著名出處!謝謝~~
[Android] Android 最全 Intent 傳遞數據姿勢