Intent详细解释,复杂数据类型传递

Intent传递数据 Intent是安卓中的一个常见组件。他的功能也有不少,比如启动活动,传递数据,启动Service, 发送广播等。这里主要对他做一个传...

Intent传递数据

Intent是安卓中的一个常见组件。他的功能也有不少,比如启动活动,传递数据,启动Service, 发送广播等。这里主要对他做一个传递数据的总结,

1.传递简单数据类型

发出数据

Intent intent = new Intent(this ,otheactivity.class);//创建Intent对象

String name = "111111";

intent.putExtra("name",name);//将数据封入intent中

startActivity(intent);//启动intent

接收数据

Intent intent = getIntent();//获取对象

String name = intent.getStringExtra("name");//取出数据

这里介绍一下Bundle,这个类可以对传递的数据进行封装,将多个数据作为一个整体进行传递。这样就可以将关联的数据打包成一个 Bundle 对象,而不需要分别使用多个 putExtra 方法进行传递,这样可以更加清晰地组织和管理数据。同时他支持进行多个Bundle进行嵌套,使他又有比较强的拓展性,他也支持复杂数据类型传递,比如进行了Parcelable 对象和Serializable 对象和集合数组等

这里给出一些方法

putExtra(String key, …) / getExtra(String key, …):用于存储和获取基本数据类型,如 putExtra(“name”, “John”) 和 getExtra(“name”)。

putParcelable(String key, Parcelable value) / getParcelable(String key):用于存储和获取 Parcelable 对象,如 putParcelable(“user”, userParcelable) 和 getParcelable(“user”)。

putSerializable(String key, Serializable value) / getSerializable(String key):用于存储和获取实现了 Serializable 接口的对象,如 putSerializable(“list”, serializableList) 和 getSerializable(“list”)。

putStringArrayList(String key, ArrayList value) / getStringArrayList(String key):用于存储和获取字符串数组列表,如 putStringArrayList(“names”, nameList) 和 getStringArrayList(“names”)。

putSparseParcelableArray(String key, SparseArray value) / getSparseParcelableArray(String key):用于存储和获取稀疏数组,其中值必须是 Parcelable 对象。

putBundle(String key, Bundle value) / getBundle(String key):用于存储和获取嵌套的 Bundle 对象,如 putBundle(“nestedData”, nestedBundle) 和 getBundle(“nestedData”)。

使用Bundle传递多个简单对象

String name = "111111";

int age = 13;

Intent intent = new Intent(this ,otheactivity.class);

Bundle bundle = new Bundle();

bundle.putString("name",name);

bundle.putInt("age",age);

intent.putExtras(bundle);

startActivity(intent);

Intent intent = getIntent();

Bundle bundle=intent.getExtras();

String name = bundle.getString("name");

int age = bundle.getInt("age");

当然这里Bundle的功能主要还是起到一个将多个数据作为一个整体进行传递的作用,其他的功能使用简单的Intent方法也可以进行实现

2.传递数组

// 创建一个包含数组的 Intent

Intent intent = new Intent(this, AnotherActivity.class);

// 传递字符串数组

String[] stringArray = {"apple", "orange", "banana"};

intent.putExtra("stringArray", stringArray);

// 传递整型数组

int[] intArray = {1, 2, 3, 4, 5};

intent.putExtra("intArray", intArray);

// 启动另一个 Activity

startActivity(intent);

// 获取传递的字符串数组

String[] receivedStringArray = getIntent().getStringArrayExtra("stringArray");

// 获取传递的整型数组

int[] receivedIntArray = getIntent().getIntArrayExtra("intArray");

3.传递集合

集合分为几种不同的情况

首先是普通的集合,这里要求集合的泛型都是基本数据类型,即不包含自定义类型

// 创建一个包含 ArrayList 的 Intent

Intent intent = new Intent(this, AnotherActivity.class);

// 准备要传递的 ArrayList

ArrayList stringArrayList = new ArrayList<>();

stringArrayList.add("apple");

stringArrayList.add("orange");

stringArrayList.add("banana");

// 传递字符串类型的 ArrayList

intent.putStringArrayListExtra("stringArrayList", stringArrayList);

// 启动另一个 Activity

startActivity(intent);

// 获取传递的字符串类型的 ArrayList

ArrayList receivedStringArrayList = getIntent().getStringArrayListExtra("stringArrayList");

其次就是集合泛型为自定义类型的集合,他们要求自定义类型实现 Serializable 接口或 Parcelable 接口,确保自定义类型是可序列化的以便能够在 Intent 之间进行传递。

public class User implements Serializable {

private String name;

private int age;

// 构造函数等其他相关代码

// 省略 getter 和 setter 方法

}

// 创建一个包含自定义类型 User 的 ArrayList 的 Intent

Intent intent = new Intent(this, AnotherActivity.class);

// 准备要传递的自定义类型 User 的 ArrayList

ArrayList userArrayList = new ArrayList<>();

User user1 = new User("Alice", 25);

User user2 = new User("Bob", 30);

userArrayList.add(user1);

userArrayList.add(user2);

// 传递自定义类型 User 的 ArrayList

intent.putExtra("userArrayList", userArrayList);

// 启动另一个 Activity

startActivity(intent);

// 获取传递的自定义类型 User 的 ArrayList

ArrayList receivedUserArrayList = (ArrayList) getIntent().getSerializableExtra("userArrayList");

这里的自定义类型实现 Serializable 接口或 Parcelable 接口,就是下面会将到的部分了

4.传递自定义类型

当我们需要在Intent中携带自定义的对象(基本数据类型在底层封装类中都已经实现过了)时,这些对象需要实现 Serializable 或 Parcelable 接口,以便能够在不同组件之间进行序列化和反序列化。

序列化指的是将对象转换为可存储或可传输的格式,例如字节流或者JSON字符串。而反序列化则是将存储或传输的数据重新转换为对象。在Android中,当我们在Intent中传递自定义对象时,系统需要将这些对象序列化为字节流,以便在不同组件之间传输或存储;接收方再将字节流反序列化为对象,以便恢复数据的完整结构。

这里在讲一下两个接口的区别

Serializable 接口

实现简单:Serializable 接口不需要编写任何方法,它只是一个标记接口(interface),用于指示类的实例可以被序列化。因此,实现 Serializable 接口非常简单,只需在类声明中添加 implements Serializable 即可。适用范围广:Serializable 接口可以用于各种 Java 程序,不仅限于 Android 开发。它是 Java 标准库中的一部分,因此在 Java 平台上很受欢迎。速度相对较慢:尽管 Serializable 接口易于使用,但在 Android 等环境下,序列化和反序列化大量数据时可能速度较慢。

Parcelable 接口

手动实现:Parcelable 接口需要手动编写序列化和反序列化的代码,包括 writeToParcel 和 createFromParcel 这两个方法。这使得它的实现相对复杂一些。高效:相比 Serializable 接口,Parcelable 更高效。它允许开发者精确地控制序列化和反序列化的过程,从而避免了一些额外的开销。主要用于 Android 开发:Parcelable 接口在 Android 开发中特别有用,尤其是在需要在 Activity 之间传递复杂对象的情况下。它通常被认为是更好的选择,特别是在需要传递大量数据的情况下。

综上所述,Serializable 接口简单易用,适用范围广,Parcelable 主要用于内存中的数据传递,而不适合用于将数据存储在磁盘上,因为它不提供对数据版本变化的支持。相比之下,Serializable 在某种程度上更适合用于数据的持久化存储,因为它可以更好地保证数据的一致性。

而Parcelable 在内存中的性能确实比 Serializable 要好,因为它可以精确地控制对象的序列化和反序列化过程,避免了创建大量临时对象。这使得在内存中传递大量数据时,Parcelable 通常比 Serializable 更高效。在实际开发中,根据具体情况选择合适的方案。

Serializable 接口和Parcelable 接口的简单使用

Serializable 接口

import java.io.Serializable;

public class SerializableObject implements Serializable {

private int id;

private String name;

public SerializableObject(int id, String name) {

this.id = id;

this.name = name;

}

public int getId() {

return id;

}

public String getName() {

return name;

}

}

之后后其他基本数据类型的使用基本一致

import android.os.Parcel;

import android.os.Parcelable;

//这里省略了构造函数和get set 函数

public class ParcelableObject implements Parcelable {

private int id;

private String name;

//这是一个特殊的构造函数,用于从Parcel中读取数据来恢复对象的状态。在这里,我们从Parcel中读取int类型的id和String类型的name,并将其赋值给对象的属性。

protected ParcelableObject(Parcel in) {

id = in.readInt();

name = in.readString();

}

public static final Creator CREATOR = new Creator() {

@Override

public ParcelableObject createFromParcel(Parcel in) {

return new ParcelableObject(in);

}

@Override

public ParcelableObject[] newArray(int size) {

return new ParcelableObject[size];

}

};

@Override

public int describeContents() {

return 0;

}

//该方法将对象的数据写入到Parcel中,以便在不同组件间进行传递。

@Override

public void writeToParcel(Parcel dest, int flags) {

dest.writeInt(id);

dest.writeString(name);

}

}

你看着这些函数可能感觉不太好写,但是他可以通过implements Parcelable 后Alt加回车得到,同时Andriod Studio中也有插件可以实现这个功能