1. 程式人生 > >[Android] Android 最全 Intent 傳遞數據姿勢

[Android] Android 最全 Intent 傳遞數據姿勢

creator 組件 itl 快捷 ras 轉載 重寫 object 推薦

我們都是用過 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 傳遞數據姿勢