首页 > 代码库 > 使用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传递对象