Passing Objects Between Android Activities

本文探讨了三种在Android活动中传递复杂对象的方法:使用Parcelable接口、利用Serializable接口及采用EventBus库。对比了它们的实现难度与效率,并推荐了EventBus作为更高效、简洁的选择。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

转自: http://www.stevenmarkford.com/passing-objects-between-android-activities/


Introduction

It is sometimes convenient to pass through a java object (POJO) from one activity to another as opposed to sending multiple separate primitives via bundle extras.
We will be looking at three different methods of passing objects between activities:

  1. The standard Android approach using the Android Parcelable class
  2. Using the standard Java Serializable interface
  3. Using a light weight (~42Kb) Android event bus library called EventBus

After trying these approaches I prefer using an event bus.

In the examples below we will assume we want to send the following POJO from one activity to another:

	public class POJO
	{
		public int integer;
		public String string;
		public Boolean bool;
		public Float f;

		public POJO(int integer, String string, Boolean bool, Float f)
		{
			this.integer = integer;
			this.string = string;
			this.bool = bool;
			this.f = f;
		}
	}

Example 1: Using Standard Android Parcelable

Step 1 Extend our POJO with the Android Parcelable base class and implement required methods…Sounds easy right? Brace yourself…the result is a mutant POJO with IBS that just ate a large loaf of white bread!

	public class POJO implements Parcelable
	{
		public int integer;
		public String string;
		public Boolean bool;
		public Float f;
		
		public POJO(int integer, String string, Boolean bool, Float f)
		{
			this.integer = integer;
			this.string = string;
			this.bool = bool;
			this.f = f;
       		}
		
		//used to deflate the POJO
		//before sending to destination activity
		@Override
		public void writeToParcel(Parcel dest, int flags)
		{
			dest.writeStringArray(new String[] 
			{
				String.valueOf(this.integer),
				this.string,
				String.valueOf(this.bool),
				String.valueOf(this.f)
			});
		}
		
		//used to inflate the POJO once it has
		//reached its destination activity
		public POJO(Parcel in)
		{
			String[] data = new String[4];
			in.readStringArray(data);
			this.integer = Integer.parseInt(data[0]);
			this.string = data[1];
			this.bool = Boolean.parseBoolean(data[2]);
			this.f = Float.parseFloat(data[3]);
		}

		//method on the interface
		@Override
		public int describeContents()
		{
			return 0;
		}
		
		//More boilerplate
		//Failure to add this results in the following exception
		//"android.os.BadParcelableException: Parcelable protocol 
		//requires a Parcelable.Creator object called  CREATOR on class"
		 public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
	           public POJO createFromParcel(Parcel in) {
	               return new POJO(in); 
	           }

	           public POJO[] newArray(int size) {
	               return new POJO[size];
	           }
	       };
	}

That POJO does not feel very Coca-Cola anymore!

Step 2 We send the POJO off to our destination activity

Intent intent = new Intent(this,Destination.class);
intent.putExtra("MyPojo", new POJO(1, "2", true, 3.0f));
this.startActivityForResult(intent,0);

Step 3 Our destination activity reads the result

Intent intent = this.getIntent();
POJO myPOJO = (POJO)intent.getParcelableExtra("MyPojo"); 

Example 2: Using Java Serializable

Step 1 Update the POJO to extend the serializable interface. The POJO doesn’t change much when using Serializable:

	public class POJO implements java.io.Serializable
	{
		public int integer;
		public String string;
		public Boolean bool;
		public Float f;

		public POJO(int integer, String string, Boolean bool, Float f)
		{
			this.integer = integer;
			this.string = string;
			this.bool = bool;
			this.f = f;
		}
	}

Step 2 We send the POJO off to our destination activity:

Intent intent = new Intent(this,Destination.class);
intent.putExtra("MyPojo", new POJO(1, "2", true, 3.0f));
this.startActivityForResult(intent,0);

Step 3 Our destination activity reads the result:

Intent intent = this.getIntent();
POJO myPOJO = (POJO)intent.getSerializableExtra("MyPojo"); 

Example 3: Using EventBus

To setup EventBus simply download the jar from here and reference it in your Android Project (see Eclipse tutorial on adding a jar to a project here), or if you using Maven then the details are: group ID “de.greenrobot” and artifact ID “eventbus”.

Step 1 We pop unmodified POJO, as is, onto the bus (no need for all that boilerplate code):

Intent intent = new Intent(this,Destination.class);
de.greenrobot.event.EventBus.getDefault().postSticky(new POJO(1, "2", true, 3.0f));
this.startActivityForResult(intent,0);

postSticky() simply persists the object on the bus and allows it to be picked up later by the destination activity.

Step 2 Our destination activity pops the POJO off the bus:

POJO myPOJO = (POJO)EventBus.getDefault().removeStickyEvent(POJO.class);

We tell the Bus to give us the last posted object of type POJO.

Notice how you no longer need magic strings to manage the key values of the bundle. You use the actual .class, which
essentially strongly-types your references.

Efficiency Comparison

Efficiency is always important, not only can little inefficiencies scattered around the code add up to large noticeable ones but overtime it can result in battery-hog.

Below is a time vs communication count chart comparing the different methods using the POJO object:
EventBus-POJO
There is not really any difference in performance for a simple POJO that only contains four fields.

Now lets pass around the following object and see what happens:

	public class MammaPOJO
	{
		public POJO[] babyPOJOS;

		public MammaPOJO(POJO[] babyPOJOS)
		{
			this.babyPOJOS = babyPOJOS;
		}
	}

EventBus-POJO-2
From the above chart you can see EventBus does not depend on the complexity of the object where as the other two approaches do.

Now for abit more fun lets look at what happens when MammaPOJO has 1000 babies.
EventBus-POJO-3

Conclusion

EventBus seems like a pretty good option: It requires a lot! less boilerplate, complements an agile coding-style, is more strongly typed (requiring less hard-coded string management) and it is a bit less of a battery-hog when it comes to complex objects.


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值