Activity 与 Service 实现Parcelable接口传递 ArrayList 集合

在 Activity 跟 Service 的通信过程中,一般用来传递数据的载体就是Intent了,一般用来传数据呢,我们都是通过putExtra 函数来传递简单的String,int, long类型的值,

但是现在存在这样一个问题:

1)在Activity里面有一个歌曲列表 List, 里面的对象是自定义的一个MusicInfo类,即 List<MusicInfo> 对象,这是用来展现的。

2)在后台Service中,也需要这样一个List<MusicInfo>, 来实现当歌曲播放结束的时候,自动循环播放或者顺序播放,或者随机播放。

我想要把整个List<MusicInfo> 给传过去,那该怎么办?

一般来说,将自定义的对象放到 Intent 里面来传递,可以有两种实现方法:

1)传递的对象实现 Serializable 接口,代码如下:

class MusicInfo implements Serializable{
		private static final long serialVersionUID = -39201440269615431L;
		...
	}
在设置 Intent 的时候,

intent.putExtra("music", new MusicInfo());

在Service 端接收 Intent 的时候,

intent.getSerializableExtra("music");

2)传递的对象实现Parcelable 接口,代码如下:

static class MusicInfo implements Parcelable{								
		private static final long serialVersionUID = -39201440269615431L;
		...

		@Override
		public void writeToParcel(Parcel dest, int flags) {
			dest.writeLong(id);
			dest.writeString(title);
			dest.writeString(album);
			dest.writeString(artist);
			dest.writeString(url);
			dest.writeLong(duration);
			dest.writeLong(size);
		}
		
		public static final Parcelable.Creator<MusicInfo> CREATOR = new Creator<MusicLoader.MusicInfo>() {
			
			@Override
			public MusicInfo[] newArray(int size) {
				// TODO Auto-generated method stub
				return new MusicInfo[size];
			}
			
			@Override
			public MusicInfo createFromParcel(Parcel source) {
				// TODO Auto-generated method stub
				MusicInfo musicInfo = new MusicInfo();
				musicInfo.setId(source.readLong());
				musicInfo.setTitle(source.readString());
				musicInfo.setAlbum(source.readString());
				musicInfo.setArtist(source.readString());
				musicInfo.setUrl(source.readString());
				musicInfo.setDuration(source.readLong());
				musicInfo.setSize(source.readLong());
				return musicInfo;
			}
		};
其中下面三个方法是实现Parcelable 接口必须实现的:

1)describeContent () : 请参考:http://stackoverflow.com/questions/4076946/parcelable-where-when-is-describecontents-used

2)writeToParcel :将 MusicInfo 类中的值写放到一个Parcel容器中,这就是用来传递值的了

3)public static final Parcelable.Creator<T> CREATOR = new Creator<T>() :这是一个静态的接口,而且其名字一定要是CREATOR (=_=!!), 里面提供了两个方法,

3.1)public T[] newArray(int size) {} :返回一个 T 类型的数组

3.2)public T createFromParcel(Parcel source) {} : 从Parcel 中获取之前写入的数据,并封装成Parcel

对于这个Creator的接口,我的理解是,当我们把数据包装到Parcel中之后,它会被包装成一个 T 类型的数组(Music[] parcel),然后传递给Service或者其它Activity的时候,当系统要将Parcel中数据重新解析成我们自定义的对象的时候,它需要去调用Creator这个接口,先根据传入对象的长度 new 出一个T数组, 然后再CreateFromParcel,将内容转化成一个一个的 T 类型对象,放到数组中,返回给接收者。

可能也正是因为封装数组这种特性,当我们要在Android中传递开篇中提到的 List<MusicInfo> 集合的时候,只能实现Parcelable接口,用Serializable 是实现不了的。

另外有一点要注意的是,我们从Parcel 解析自定义的对象的时候,顺序必须跟我们写进去的顺序一致。

传送跟接收自定义的List<MusicInfo> 的代码如下:

intent.putParcelableArrayListExtra(NatureService.MUSICS, (ArrayList<? extends Parcelable>) musicList);
musicList = intent.getParcelableArrayListExtra(MUSICS);

我也尝试过让MusicInfo 去实现Serializable 接口,然后放到Intent 中来传送,但是没办法实现,会爆出以下的Exception.


看 Log,其还是用parcelable 接口去解析的。

P.S. 我的MusicInfo是一个子类,所以必须是静态子类,否则定义public, static 的 CREATOR 接口中时,是会错误的。




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值