首页 > 代码库 > 使用Intent传递对象

使用Intent传递对象

我们可以借助Intent来启动活动,发送广播,启动服务等。

还可以通过putExtra()方法传递一些数据。

但我们会发现putExtra()方法中所支持的类型是有限的。当我们想去传递一些自定义对象的时候,会发现无法通过putExtra()的方法进行传递。

但Intent是可以传递对象的。

使用Intent传递对象的通常有两种方式 Serializable Parcelable

Serializable方式

Serializable是序列化的意思,表示将一个对象转换成可存储或可传输的状态。序列化后的对象可以在网络上进行传输,也可以存储到本地。

 

序列化的方法: 只需要让一个类去实现Serializable这个接口就可以了。

创建一个SerializableTest项目,并增加两个Activity,一个名为FristActivity,一个名为SecondActivity。

新建一个Person类并实现Serializable接口,代码如下
 1 public class Person implements Serializable{
 2     private String name;
 3 
 4     public String getName() {
 5         return name;
 6     }
 7 
 8     public void setName(String name) {
 9         this.name = name;
10     }
11 }

这里仅有一个name字段。

 

修改FirstActivity中的代码
 1 public class FirstActivity extends AppCompatActivity {
 2 
 3     @Override
 4     protected void onCreate(Bundle savedInstanceState) {
 5         super.onCreate(savedInstanceState);
 6         setContentView(R.layout.activity_first);
 7         Person person = new Person();
 8         person.setName("张三");
 9         Intent intent = new Intent(FirstActivity.this,SecondActivity.class);
10         intent.putExtra("person_data",person);
11         startActivity(intent);
12     }
13 }

实现序列化后,Person对象可以像其他数据一样通过putExtra()方法传输。

修改SecondActivity中的代码
 1 public class FirstActivity extends AppCompatActivity {
 2 
 3     @Override
 4     protected void onCreate(Bundle savedInstanceState) {
 5         super.onCreate(savedInstanceState);
 6         setContentView(R.layout.activity_first);
 7         Person person = new Person();
 8         person.setName("张三");
 9         Intent intent = new Intent(FirstActivity.this,SecondActivity.class);
10         intent.putExtra("person_data",person);
11         startActivity(intent);
12     }
13 }

这里调用了getSerializableExtra()方法来获取参数传递过来的序列化对象。

 

运行程序,发现已经成功传递打印出来。

技术分享

 


 

Parcelable方式 

Parcelable方式的实现原理是将一个完整的对象进行分解,而分解后的每一部分都是Intent所支持的数据类型。这样也就实现传递对象的功能了。

修改Person类中的代码
 1 public class Person implements Parcelable{
 2     private String name;
 3 
 4     public String getName() {
 5         return name;
 6     }
 7 
 8     public void setName(String name) {
 9         this.name = name;
10     }
11 
12     @Override
13     public int describeContents() {
14         return 0;
15     }
16 
17     @Override
18     public void writeToParcel(Parcel dest, int flags) {
19         dest.writeString(name); //写出name
20     }
21 
22     public static final Parcelable.Creator<Person> CREATOR = new Parcelable.Creator<Person>(){
23         @Override
24         public Person createFromParcel(Parcel source) {
25             Person person = new Person();
26             person.name = source.readString();
27             return person;
28         }
29 
30         @Override
31         public Person[] newArray(int size) {
32             return new Person[size];
33         }
34     };
35 }

这里首先让Person类实现了Parcelable接口。

实现Parcelable接口后就必须重写describeContents()和writeToParcel()这两个方法。

其中describeContents()方法直接返回0就可以了。

而writeToParcel()方法中需要调用Parcel的writeXXX()方法。将Person类中的字段写出。

写出字符串型数据就要调用writeString()方法。依次类推。

除此之外还必须在Person类中提供一个名为CREATOR的常量。

这里创建了一个Parcelable.Creator接口的一个实现,并将泛型指定为Person。

接着需要重写createFromParcel()和new Array()这两个方法。

在createFromParcel()方法中我们要去读取刚才写出的name字段,并创建一个Person对象返回。

其中name字段都是通过readXXX()方法读取到的。

注意这里读取的顺序一定要和刚才写出的顺序完全一致。

而newArray()方法中只需要new出一个Person数组,并使用方法中传入的size作为数组大小就可以了。

修改SecondActivity中的代码
 1 public class SecondActivity extends AppCompatActivity {
 2 
 3     private static final String TAG = "SecondActivity";
 4 
 5     @Override
 6     protected void onCreate(Bundle savedInstanceState) {
 7         super.onCreate(savedInstanceState);
 8         setContentView(R.layout.activity_second);
 9         Person person = (Person)getIntent().getParcelableExtra("person_data");
10         Log.d(TAG, "Name:" + person.getName());
11     }
12 }

这里不是再调用getSerializableExtra()方法,而是调用getParcelableExtra()方法。

其他的地方完全一致。


 

 

Serializable的方式较为简单,但由于会将整个对象进行序列化,因此效率会比Parcelable方式低一些,所以在通常情况下还是更加推荐使用Parcelable的方式来实现Intent传递对象的功能。

使用Intent传递对象