前言

Intent除了来启动activity,发送广播,启动服务等。我们还可以在Intent中添加数据,以达到在两个activity传递数据的作用。

我们可以这样传递一些简单的数据:

Intent intent = new Intent(FirstActivity.this, SecondActivity.class);
    intent.putExtra("username", "zhangsan");
    intent.putExtra("password", "123456");
    startActivity(intent);

那么在SecondActivity.java中,接可以这样获取:

String username = getIntent().getStringExtra("username");
    String password = getIntent().getIntExtra("password");

但是如何传递对象呢?

这里有两种方式:

  • Serializable
  • Parcelable

第一种:Serializable方式

Serializable是序列化的意思,表示将一个对象转换成可存储或可传输的状态。序列化后的对象可以在网络上进行传输,也可以存储到本地。至于序列化的方法也很简单,只需要让一个类去实现 Serializable 这个接口就可以了。

比如说下面的Person类:

public class Person implements Serializable {

        public String userName;

        public String passWord;

        // get and set method ...
    }

接下来,我们在FirstActivity中传递这个对象到SecondActivity中:

Person person = new Person();
    person.setUserName("zhangsan");
    person.setPassWord("123456");

    Intent intent = new Intent(FirstActivity.this, SecondActivity.class);
    intent.putExtral("person", intent);
    startActivity(intent);

在SecondActivity.java中获取:

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

第二种:Parcelable方式

Parcelable方式能达到Serializable方式相同的效果。

下面我们来看一下 Parcelable 的实现方式,修改 Person 中的代码,如下所示:

public class Person implements Parcelable {

        public String userName;

        public String passWord;

        // get and set method ...

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

        @Override
        public void writeToParcel(Parcel dest, int flags) {
            dest.writeString(username); //  写出username
            dest.writestring(password); //  写出password
        }

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

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

Parcelable的实现方式要稍微复杂一些,实现接口后,重写两个方法:

  • describeContents(); 这个方法不需要管,直接返回0即可
  • writeToParcel(Parcel dest, int flags); 此方法中我们需要调用 Parcel的 writeXxx()方法将 Person 类中的字段一一写出

Tips:在writeToParcel()方法中将对象相关字段按照相应的数据类型写入,但是提供的写入方法中却没有写入boolean类型的方式:
这里提供一种解决方式->
写 : dest.writeByte((byte) (yourBoolean ? 1 : 0));
读 : yourBoolean = source.readByte() == 1;

注意:字符串型数据就调用 writeString()方法,整型数据就调用 writeInt()方法,以此类推。

除此之外,我们还必须在 Person 类中提供一个名为 CREATOR 的常量,这里创建了Parcelable.Creator 接口的一个实现,并将泛型指定为 Person。接着需要重写 createFromParcel()newArray()这两个方法,在 createFromParcel()方法中我们要去读取刚才写出的 name 和 age字段,并创建一个 Person 对象进行返回,其中 name 和 age 都是调用 Parcel 的 readXxx()方法读取到的,注意这里读取的顺序一定要和刚才写出的顺序完全相同。而 newArray()方法中的实现就简单多了,只需要 new 出一个 Person 数组,并使用方法中传入的 size 作为数组大小就可以了。

接下来,在FirstActivity中传递的方式不变,在SecondActivity中获取的方式要改变一下:

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

总结

虽然两种方式都能达到相同效果,但是我们还是建议使用Parcelable方式来传递数据,原因是,Serializable方式会将整个对象进行序列化,效率方面要低,从事终端开发,对效率要求还是比较高的。