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

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的成员变量


希望上面的能帮到你,有什么不懂的,可以问我,如果需要源码也可以留下邮箱,到时发给你。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值