Android中Intent传递对象的两种方法Serializable,Parcelable

时间:2021-12-20 07:23:02

Android中的传递有两个方法,一个是Serializable,另一个是Parcelable。

Serializable是J2SE本身就支持的。而Parcelable是Android所特有的。

二者的使用场景和区别:

1)在使用内存的时候,Parcelable比Serializable性能高,所以推荐使用Parcelable。

2)Serializable在序列化的时候会产生大量的临时变量,从而引起频繁的GC。

3)Parcelable不能使用在要将数据存储在磁盘上的情况,因为Parcelable不能很好的保证数据的持续性在外界有变化的情况下。尽管Serializable效率低点,但此时还是建议使用Serializable 。

Serializable接口实现比较简单,只要实现setter和getter,就可以了。

而Parcelable实现比较麻烦些。用一个小的demo来说明:

1.新建android项目ObjectTranDemo

2.创建一个entity的javaBean:Person.java.实现Serializable接口

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package com.example.objecttrandemo;
import java.io.Serializable;
public class Person implements Serializable {
private static final long serialVersionUID = -7060210544600464481L;
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;
}
}

3.创建主界面activity_main.xml:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="android object trance"
/>
<Button
android:id="@+id/button1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Serializable"
/>
<Button
android:id="@+id/button2"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Parcelable"
/>
</LinearLayout>

4.创建主activity。这个activity主要用来响应点击事件,和传递数据。ObjecttranDemo.java:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
package com.example.objecttrandemo;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
public class ObjectTranDemo extends Activity implements OnClickListener{
private Button sButton,pButton;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setupViews();
}
//initial the views
public void setupViews(){
sButton = (Button)findViewById(R.id.button1);
pButton = (Button)findViewById(R.id.button2);
sButton.setOnClickListener(this);
pButton.setOnClickListener(this);
}
//Serializeable object trance
public void SerializeMethod(){
Person mPerson = new Person();
mPerson.setName("durant");
mPerson.setAge(25);
Intent mIntent = new Intent(this,ObjectTranDemo1.class);
Bundle mBundle = new Bundle();
mBundle.putSerializable("mPerson",mPerson);
mIntent.putExtras(mBundle);
startActivity(mIntent);
}
//Pacelable object trance
public void PacelableMethod(){
Book mBook = new Book();
mBook.setBookName("a man from mars");
mBook.setAuthor("james");
mBook.setPublishTime(2014);
Intent mIntent = new Intent(this,ObjectTranDemo2.class);
Bundle mBundle = new Bundle();
mBundle.putParcelable("mBook", mBook);
mIntent.putExtras(mBundle);
startActivity(mIntent);
}
@Override
public void onClick(View v) {
if(v == sButton){
SerializeMethod();
}else{
PacelableMethod();
}
}
}

5.新建activity ObjectTranDemo1.java用来显示Serializable接口传递过来的数据

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
package com.example.objecttrandemo;
import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;
public class ObjectTranDemo1 extends Activity{
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
TextView mTextView = new TextView(this);
Person mPerson = (Person)getIntent().getSerializableExtra("mPerson");
mTextView.setText("You name is: " + mPerson.getName() + "\n"+
"You age is: " + mPerson.getAge());
setContentView(mTextView);
}
}

至此,Serializable接口传递数据完毕,对了,别忘了,在Mainfest.xml文件中声明新的activity

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.objecttrandemo"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="18" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name="com.example.objecttrandemo.ObjectTranDemo"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".ObjectTranDemo1"></activity>
<activity android:name=".ObjectTranDemo2"></activity>
</application>
</manifest>

下面看Parcelable的传递:

实现Parcelable一般需要4个步骤:

1)implements Parcelable

2)重写writeToParcel方法,将你的对象序列化为一个Parcel对象,即:将类的数据写入外部提供的Parcel中,打包需要传递的数据到Parcel容器保存,以便从 Parcel容器获取数据

3)重写describeContents方法,内容接口描述,默认返回0就可以

4)实例化静态内部对象CREATOR实现接口Parcelable.Creator

public static final Parcelable.Creator<T> CREATOR

注:其中public static final一个都不能少,内部对象CREATOR的名称也不能改变,必须全部大写。需重写本接口中的两个方法:createFromParcel(Parcel in) 实现从Parcel容器中读取传递数据值,封装成Parcelable对象返回逻辑层,newArray(int size) 创建一个类型为T,长度为size的数组,仅一句话即可(return new T[size]),供外部类反序列化本类数组使用。

简而言之:通过writeToParcel将你的对象映射成Parcel对象,再通过createFromParcel将Parcel对象映射成你的对象。也可以将Parcel看成是一个流,通过writeToParcel把对象写到流里面,在通过createFromParcel从流里读取对象,只不过这个过程需要你来实现,因此写的顺序和读的顺序必须一致。

具体:

1.新建Book的实体类:

Book.java:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
package com.example.objecttrandemo;
import android.os.Parcel;
import android.os.Parcelable;
public class Book implements Parcelable{
private String bookName;
private String author;
private int publishTime;
public String getBookName() {
return bookName;
}
public void setBookName(String bookName) {
this.bookName = bookName;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public int getPublishTime() {
return publishTime;
}
public void setPublishTime(int publishTime) {
this.publishTime = publishTime;
}
//Internal Description Interface,You do not need to manage
@Override
public int describeContents() {
return 0;
}
//give some attention to the oder betwwen writeToParcel and createFromParcel
@Override
public void writeToParcel(Parcel parcel, int flags){
parcel.writeString(bookName);
parcel.writeString(author);
parcel.writeInt(publishTime);
}
public static final Parcelable.Creator<Book> CREATOR = new Creator<Book>() {
@Override
public Book[] newArray(int size) {
return new Book[size];
}
@Override
public Book createFromParcel(Parcel source) {
Book mBook = new Book();
mBook.bookName = source.readString();
mBook.author = source.readString();
mBook.publishTime = source.readInt();
return mBook;
}
};
}

2.新建activity :ObjectTranDemo2.java.用来显示parcelable的数据:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
package com.example.objecttrandemo;
import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;
public class ObjectTranDemo2 extends Activity{
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
TextView mTextView = new TextView(this);
Book mBook = (Book)getIntent().getParcelableExtra("mBook");
mTextView.setText("Book name is: " + mBook.getBookName()+"\n"+
"Author is: " + mBook.getAuthor() + "\n" +
"PublishTime is: " + mBook.getPublishTime());
setContentView(mTextView);
}
}

在上篇文章给大家介绍了,Intent传递对象之Serializable和Parcelable的区别,感兴趣的朋友可以点击了解详情。