您的位置:首页 > 移动开发 > Android开发

Android中不同Activity之间传递自定义对象的参数问题的解决

2013-05-03 23:13 816 查看
Android中不同Activity之间传递自定义对象的参数问题的解决

本人最近刚接触Android开发,在不同activity之间传递自己定义的数据结构时,出现了各种各样的问题,后面会一一列举,上网搜资料都是一些简单的Demo,根本就没有稍微复杂点的,为了使后来者不走我的老路,故把我遇到的问题一一解答,希望给大家有帮助。

首先,大家都知道要在不同的activity之间传递自己定义的数据结构,那么该数据结构必须实现Serializable或Parcelable接口,两者的区别我就不讲了,网上有许多的介绍,我这里重点介绍下在实现Parcelable接口下的实现,因为实现了Parcelable接口的好处就是所有的序列化都是自己实现,而不像Serializable全是系统实现的,因而数据结构中使用到的其他对象也都必须实现Serializable,而有些像JSONObject或JSONArray这样的对象,系统是没有实现Serializable接口的,这样我们就不能使用Serializable来实现序列化了,从而Parcelable的优势就显示出来了。下面通过一个Demo来讲解:

这里先介绍下类之间的关系:

下面是自定义的Content.java:

public class Content implements Parcelable{

private static final long serialVersionUID = -5569454732667167419L;

private String
m_strCid;

private String
m_strTitle;

private String
m_strSubTitle;

private List<String>
m_strTags;

private Image
m_thumbImage;

private Location
m_location;

private Image
m_previewImage;

private List<Page> m_pages;

public static final Parcelable.Creator<Content> CREATOR= new Parcelable.Creator<Content>() {

@Override

public Content createFromParcel(Parcel source) {

Content content= new Content();

//必须按成员变量的顺序读取值, 这里必须注意:一定按成员变量的顺序写,此处是获得值,相当于读取流中的数据

content.m_strCid = source.readString();

content.m_strTitle = source.readString();

content.m_strSubTitle = source.readString();

content.m_strTags = new ArrayList<String>();

source.readList(content.m_strTags, getClass().getClassLoader());

content.m_thumbImage = (Image) source.readSerializable();

content.m_location = (Location)source.readParcelable(Location.class.getClassLoader());

//content.m_location = (Location)source.readSerializable();

content.m_previewImage = (Image)source.readSerializable();

//必须实例化,注意List集合的处理

content.m_pages = new ArrayList<Page>();

source.readList(content.m_pages, getClass().getClassLoader());

return content;

}

@Override

public Content[] newArray(int size) {

// TODO Auto-generated method stub

return new Content[size];

}

};

@Override

public int describeContents() {

// TODO Auto-generated method stub

return 0;

}

@Override

public void writeToParcel(Parcel dest, int flags) {

dest.writeString(m_strCid);

dest.writeString(m_strTitle);

dest.writeString(m_strSubTitle);

dest.writeList(m_strTags);

dest.writeSerializable(m_thumbImage);

dest.writeParcelable(m_location, PARCELABLE_WRITE_RETURN_VALUE);

dest.writeSerializable(m_previewImage);

dest.writeList(m_pages);

}

public Content(){

}

public String getCid() {

return m_strCid;

}

public void setCid(String cid) {

m_strCid = cid;

}

public String getTitle() {

return m_strTitle;

}

public void setTitle(String title) {

m_strTitle = title;

}

public String getSubTitle() {

return m_strSubTitle;

}

public void setSubTitle(String subTitle) {

m_strSubTitle = subTitle;

}

public List<String> getTags() {

return m_strTags;

}

public void setTags(List<String> tags) {

m_strTags = tags;

}

public Image getThumbImage() {

return m_thumbImage;

}

public void setThumbImage(Image thumbImage) {

m_thumbImage = thumbImage;

}

public Location getLocation() {

return m_location;

}

public void setLocation(Location location) {

m_location = location;

}

public Image getPreviewImage() {

return m_previewImage;

}

public void setPreviewImage(Image previewImage) {

m_previewImage = previewImage;

}

public List<Page> getPages() {

return m_pages;

}

public void setPages(List<Page> pages) {

m_pages = pages;

}

@Override

public boolean equals(Object obj){

if(obj !=null && obj instanceof LSContent){

LSContent lsContent=(LSContent) obj;

return m_strCid.equals(lsContent.m_strCid);

}

return false;

}

@Override

public int hashCode() {

int hashcode = 17 ;

if (m_strCid != null) hashcode = 31 * hashcode + m_strCid.hashCode();

return hashcode ;

}

}

下面是自定义的Image.java:

public class Image implements Serializable{

private static final long serialVersionUID = -4131250029821680992L;

private String m_strImgId;

private String m_strUrl;

private String m_strDesc;

private Float m_fWidth;

private Float m_fheight;

public Image(){

}

public String getImgId() {

return m_strImgId;

}

public void setImgId(String imgId) {

m_strImgId = imgId;

}

public String getUrl() {

return m_strUrl;

}

public void setUrl(String url) {

m_strUrl = url;

}

public String getDesc() {

return m_strDesc;

}

public void setDesc(String desc) {

m_strDesc = desc;

}

public Float getWidth() {

return m_fWidth;

}

public void setWidth(Float width) {

m_fWidth = width;

}

public Float getHeight() {

return m_fheight;

}

public void setHeight(Float height) {

m_fheight = height;

}

public String description(){

return String.format("uri:%1$s", m_strUrl);

}

}

下面是自定义的Page.java:

public class Page implements Parcelable{

private static final long serialVersionUID = 4041346749134089959L;

private String m_strViewName;

private String m_strContentId;

private Image m_preImage;

private Map<String,Object> m_mapPageStructure;
//注意:本人对Map对象的处理,这可是本人花了九牛二虎之力才找到的

public static final Parcelable.Creator<Page> CREATOR = new Parcelable.Creator<Page>() {

@SuppressWarnings("unchecked")

public Page createFromParcel(Parcel source) {

Page p=new Page();

p.m_strViewName=source.readString();

p.m_strContentId=source.readString();

p.m_preImage=(Image)source.readSerializable();

//同理下面是对Map对象的读取,也必须使用readbundle(),成对使用

p.m_mapPageStructure = new HashMap<String, Object>();

Bundle bundle=source.readBundle();

Set<String> bkeySet= bundle.keySet();

Iterator<String> it=bkeySet.iterator();

while(it.hasNext()){

String keyString=it.next();

p.m_mapPageStructure.put(keyString, bundle.get(keyString));

}

return p;

}

public Page[] newArray(int size) {

return new Page[size];

}

};

@Override

public int describeContents() {

// TODO Auto-generated method stub

return 0;

}

@Override

public void writeToParcel(Parcel dest, int flags) {

dest.writeString(m_strViewName);

dest.writeString(m_strContentId);

dest.writeSerializable(m_preImage);

//下面是对Map对象的处理,一定要转化为Bundle对象,然后进行读写,这里千万不要使用writeMap(),

Set<String> set=m_mapPageStructure.keySet();

Iterator<String> it=set.iterator();

Bundle bundle=new Bundle();

while (it.hasNext()) {

String key=it.next();

Log.e(key, m_mapPageStructure.get(key).toString());

bundle.putString(key, m_mapPageStructure.get(key).toString());

}

dest.writeBundle(bundle);

}

public Page(){

}

public String getContentId() {

return m_strContentId;

}

public void setContentId(String contentId) {

m_strContentId = contentId;

}

public String getViewName() {

return m_strViewName;

}

public Image getPreImage() {

return m_preImage;

}

public void setPreImage(Image preImage) {

m_preImage = preImage;

}

public void setViewName(String viewName) {

m_strViewName = viewName;

}

public Image getPreviewImage() {

return m_preImage;

}

public void setPreviewImage(Image previewImage) {

m_preImage = previewImage;

}

public Map<String,Object> getPageStructure() {

return m_mapPageStructure;

}

public void setPageStructure(Map<String,Object> pageStructure) {

m_mapPageStructure = pageStructure;

}

}

上面本人对自己定义数据结构中可能会使用到的常用类型,如List,Map等都有介绍了,现在看看你还有什么不懂的,那么在不同activity之间传递自己的数据应该没问题了吧。

下面来对可能遇到的问题进行总结:

1.Caused by:java.lang.RuntimeException: Parel:unable to marshal value {....}

这是因为你有对象没有序列化成功,在上面的例子中,我就遇到了很多次,后来花了很久才找到了,是对Map对象的处理没有处理好,把它改成bundle后才解决了次问题。

2.如果在你确定代码没有明显的问题时,运行后总是出现“sources not found”

这可能是你在实现了Serializable的类中有成员变量是另外一个自己定义类对象但你实现的是Parcelable接口,因为总是出现上面的问题,但是反过来就是可以的,即:实现的是Parcelable接口的类中可以有实现Serializable的成员变量

希望上面的能帮到你,有什么不懂的,可以问我,如果需要源码也可以留下邮箱,到时发给你。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐