参考自《第一行代码》——郭霖

Intent的用法相信你已经比较熟悉了,我们可以借助它来启动活动、发送广播、启动服务等。在进行上述操作的时候,我们还可以在Intent中添加一些附加数据,以达到传值的效果,比如在FirstActivity中添加如下代码:

Intent intent = new Intent(FirstActivity.this, SecondActivity.class);
intent.putExtra("string_data", "hello");
intent.putExtra("int_data", 100);
startActivity(intent);

这里调用了Intent的putExtra()方法来添加要传递的数据,之后在SecondActivity中就可以得到这些值了,代码如下所示:

getIntent().getStringExtra("string_data");
getIntent().getIntExtra("int_data", 0);

但是不知道你有没有发现,putExtra()方法中所支持的数据类型是有限的,虽然常用的一些数据类型它都会支持,但是当你想去传递一些自定义对象的时候就会发现无从下手。不用担心,下面我们就学习一下使用Intent来传递对象的技巧。

一、Serializable方式

使用Intent来传递对象通常有两种实现方式,Serializable和Parcelable,本小节中我们先来学习一下第一种的实现方式。
Serializable是序列化的意思,表示将一个对象转换成可存储或可传输的状态。序列化后的对象可以在网络上进行传输,也可以存储到本地。至于序列化的方法也很简单,只需要让一个类去实现Serializable这个接口就可以了。
比如说有一个Person类,其中包含了name和age这两个字段,想要将它序列化就可以这样写:

public class Person implements Serializable {
    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;
    }
}

其中get、set方法都是用于赋值和读取字段数据的,最重要的部分是在第一行。这里让Person类去实现了Serializable接口,这样所有的Person对象就都是可序列化的了。
接下来在FirstActivity中的写法非常简单:

Person person = new Person();
person.setName("Tom");
person.setAge(20);
Intent intent = new Intent(FirstActivity.this, SecondActivity.class);
intent.putExtra("person_data", person);
startActivity(intent);

可以看到,这里我们创建了一个Person的实例,然后就直接将它传入到putExtra()方法中了。由于Person类实现了Serializable接口,所以才可以这样写。
接下来在SecondActivity中获取这个对象也很简单,写法如下:

Person person = (Person) getIntent().getSerializableExtra("person_data");

这里调用了getSerializableExtra()方法来获取通过参数传递过来的序列化对象,接着再将它向下转型成Person对象,这样我们就成功实现了使用Intent来传递对象的功能了。

二、Parcelable方式

除了Serializable之外,使用Parcelable也可以实现相同的效果,不过不同于将对象进行序列化,Parcelable方式的实现原理是将一个完整的对象进行分解,而分解后的每一部分都是Intent所支持的数据类型,这样也就实现传递对象的功能了。
下面我们来看一下Parcelable的实现方式,修改Person中的代码,如下所示:

public class Person implements Parcelable {
    private String name;
    private int age;

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

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(name); // 写出name
        dest.writeInt(age); // 写出age
    }

    public static final Parcelable.Creator<Person> CREATOR = new Parcelable.Creator<Person>() {
        @Override
        public Person createFromParcel(Parcel source) {
            Person person = new Person();
            person.name = source.readString(); // 读取name
            person.age = source.readInt(); // 读取age
            return person;
        }

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

Parcelable的实现方式要稍微复杂一些。可以看到,首先我们让Person类去实现了Parcelable接口,这样就必须重写describeContents()和writeToParcel()这两个方法。其中describeContents()方法直接返回0就可以了,而writeToParcel()方法中我们需要调用Parcel的writeXxx()方法将Person类中的字段一一写出。注意字符串型数据就调用writeString()方法,整型数据就调用writeInt()方法,以此类推。
除此之外,我们还必须在Person类中提供一个名为CREATOR的常量,这里创建了Parcelable.Creator接口的一个实现,并将泛型指定为Person。接着需要重写createFromParcel()和newArray()这两个方法,在createFromParcel()方法中我们要去读取刚才写出的name和age字段,并创建一个Person对象进行返回,其中name和age都是调用Parcel的readXxx()方法读取到的,注意这里读取的顺序一定要和刚才写出的顺序完全相同。而newArray()方法中的实现就简单多了,只需要new出一个Person数组,并使用方法中传入的size作为数组大小就可以了。
接下来在FirstActivity中我们仍然可以使用相同的代码来传递Person对象,只不过在SecondActivity中获取对象的时候需要稍加改动,如下所示:

Person person = (Person) getIntent().getParcelableExtra("person_data");

注意这里不再是调用getSerializableExtra()方法,而是调用getParcelableExtra()方法来获取传递过来的对象了,其他的地方都完全相同。
这样我们就把使用Intent来传递对象的两种实现方式都学习完了,对比一下,Serializable的方式较为简单,但由于会把整个对象进行序列化,因此效率方面会比Parcelable方式低一些,所以在通常情况下还是更加推荐使用Parcelable的方式来实现Intent传递对象的功能。

android#使用Intent传递对象的更多相关文章

  1. Android中Intent传递对象的两种方法(Serializable,Parcelable)

    今天要给大家讲一下Android中 Intent中如何传递对象,就我目前所知道的有两种方法,一种是Bundle.putSerializable(Key,Object);另一种是 Bundle.putP ...

  2. [转]Android中Intent传递对象的两种方法(Serializable,Parcelable)

    http://blog.csdn.net/xyz_lmn/article/details/5908355 今天要给大家讲一下Android中Intent中如何传递对象,就我目前所知道的有两种方法,一种 ...

  3. Android高手进阶教程(十七)之---Android中Intent传递对象的两种方法(Serializable,Parcelable)!

    [转][原文] 大家好,好久不见,今天要给大家讲一下Android中Intent中如何传递对象,就我目前所知道的有两种方法,一种是Bundle.putSerializable(Key,Object); ...

  4. 【转】Android中intent传递对象和Bundle的用法

    原文网址:http://blog.csdn.net/lixiang0522/article/details/8642202 android中的组件间传递的对象一般实现Parcelable接口,当然也可 ...

  5. Android通过Intent传递对象

    1.传递Serializable方式类对象 首先创建一个序列化类:User import java.io.Serializable; public class User implements Seri ...

  6. Intent传递对象的几种方式

    原创文章.转载请注明 http://blog.csdn.net/leejizhou/article/details/51105060 李济洲的博客 Intent的使用方法相信你已经比較熟悉了,Inte ...

  7. Android 通过 Intent 传递类对象或list对象

    (转:http://www.cnblogs.com/shaocm/archive/2013/01/08/2851248.html) Android中Intent传递类对象提供了两种方式一种是 通过实现 ...

  8. Android 全局获取 Context 与使用 Intent 传递对象

    =====================全局获取 Context======================== Android 开发中很多地方需要用到 Context,比如弹出 Toast.启动活 ...

  9. Android 通过 Intent 传递类对象

    Android中Intent传递类对象提供了两种方式一种是 通过实现Serializable接口传递对象,一种是通过实现Parcelable接口传递对象. 要求被传递的对象必须实现上述2种接口中的一种 ...

随机推荐

  1. Oracle 连接排序

    ---左联操作SELECT e.* FROM hs_opt_ewb e left join hs_workform_main m on e.ewb_no=m.ewb_nowhere e.ewb_no= ...

  2. 【方法】如何实现图片压缩并使用FormData上传

    在前端上传图片的操作过程中,当上传服务器时,如果图片过大,可能会影响页面响应速度,这个时候,我们便会对图片进行压缩处理,再上传服务器. 前端对图片进行压缩,一般使用canvas来实现.最后使用canv ...

  3. fatal: refusing to merge unrelated histories(git pull)

    https://blog.csdn.net/lindexi_gd/article/details/52554159 (refusing to merge unrelated histories) ht ...

  4. PHP mysqli_init() 函数

    定义和用法 mysqli_init() 函数初始化 MySQLi 并返回 mysqli_real_connect() 使用的对象. 语法 mmysqli_init();   实例 mysqli_ini ...

  5. VO、DTO、POJO、PO的区别

    VO 即value object值对象.主要体现在视图的对象,对于一个WEB页面将整个页面的属性封装成一个对象.然后用一个VO对象在控制层与视图层进行传输交换. DTO 经过处理后的PO,可能增加或者 ...

  6. FTP基础

      FTP服务 只要有一种数据存储格式 :解析库 ,不同解析库需要不同查询方式 nsswitch 框架 平台 (每一种程序自己不再负责实时名称解析的功能,而是将这种功能委托给nsswitch) S/M ...

  7. 1.7 JAVA异常总结

    1.7 JAVA异常总结 异常有的是因为用户错误引起,有的是程序错误引起的,还有其它一些是因为物理错误引起的. 三种异常:分别为检查性异常(一般异常).运行时异常(非检查性异常).错误 Throwab ...

  8. async for 在爬虫中的使用例子

    import asyncio import re import typing from concurrent.futures import Executor, ThreadPoolExecutor f ...

  9. IntelliJ IDEA 2017.3 多模块右边栏 maven projects,maven项目命名问题

    我新建了一个maven web 模块,命名为cloud-access,可是install的时候,名字突然变为cloud-access Maven Webapp了,我就纳闷了,怎么回事.找了很久没发现原 ...

  10. Final阶段贡献分配规则

    此次作业要求参见:https://edu.cnblogs.com/campus/nenu/2019fall/homework/10063 贡献分分配规则: 组内一共五名同学,贡献分共计50分. 1.每 ...