2017-06-06 88 views
1

我正在使用Parcelable在片段之间进行通信。一切都运行良好,但有时,当Android杀死应用程序进程释放内存和用户返回到应用程序时,Parcelable从数组中获得大量项目,如数百万项而不是2-3,当然它会抛出OOM。 我想CREATOR有什么问题,但我无法处理它。Parcelable从阵列中获取巨大的无限项目直到OOM

基类:

public abstract class BaseRs implements Parcelable { 

private String token; 
private String msgAlert; 
private String simpleMsg; 
private AdsObj adsObj;  
private Map<String, String> mapSettings; 

//getters & setters 

public BaseRs() { 
} 


protected BaseRs(Parcel in) { 
    token = in.readString(); 
    msgAlert = in.readString(); 
    simpleMsg = in.readString(); 
    adsObj = in.readParcelable(AdsObj.class.getClassLoader()); 
    mapSettings = MapParcelable.readParcelable(in); 
} 

@Override 
public void writeToParcel(Parcel dest, int flags) { 
    dest.writeString(token); 
    dest.writeString(msgAlert); 
    dest.writeString(simpleMsg); 
    dest.writeParcelable(adsObj, flags); 
    MapParcelable.writeToParcel(dest, mapSettings); 
} 

} 

子类

public class GetSalesItemsRs extends BaseRs { 

private SaleCoinItem[] coinPacksArray; 

//getters+ setters 


protected GetSalesItemsRs(Parcel in) { 
    super(in); 
    coinPacksArray = in.createTypedArray(SaleCoinItem.CREATOR); 
} 

@Override 
public void writeToParcel(Parcel dest, int flags) { 
    super.writeToParcel(dest, flags); 
    dest.writeTypedArray(coinPacksArray, flags); 
} 

@Override 
public int describeContents() { 
    return 0; 
} 

public static final Creator<GetSalesItemsRs> CREATOR = new Creator<GetSalesItemsRs>() { 
    @Override 
    public GetSalesItemsRs createFromParcel(Parcel in) { 
     return new GetSalesItemsRs(in); 
    } 

    @Override 
    public GetSalesItemsRs[] newArray(int size) { 
     return new GetSalesItemsRs[size]; 
    } 
    }; 
} 

和我的兴趣对象

public class SaleCoinItem implements Parcelable { 

private int amount; 
private double price; 
private int sortOrder; 

//getters & setters 

protected SaleCoinItem(Parcel in) { 
    amount = in.readInt(); 
    price = in.readDouble(); 
    sortOrder = in.readInt(); 
} 

@Override 
public void writeToParcel(Parcel dest, int flags) { 
    dest.writeInt(amount); 
    dest.writeDouble(price); 
    dest.writeInt(sortOrder); 
} 

@Override 
public int describeContents() { 
    return 0; 
} 

public static final Creator<SaleCoinItem> CREATOR = new Creator<SaleCoinItem>() { 
    @Override 
    public SaleCoinItem createFromParcel(Parcel in) { 
     return new SaleCoinItem(in); 
    } 

    @Override 
    public SaleCoinItem[] newArray(int size) { 
     return new SaleCoinItem[size]; 


     } 
    }; 
} 
为parcelable的代码是从超类和子类和我感兴趣的物品类别组成

函数包裹地图 - 也许这里是错误;)

public class MapParcelable { 

public static void writeToParcel(Parcel out, Map<String, String> map) { 
    if (map != null) { 
     out.writeInt(map.size()); 
     for (Map.Entry<String, String> entry : map.entrySet()) { 
      out.writeString(entry.getKey()); 
      out.writeString(entry.getValue()); 
     } 
    } 
} 

public static Map<String, String> readParcelable(Parcel parcel) { 
    Map<String, String> map = new HashMap<String, String>(); 
    int size = parcel.readInt(); 
    for (int i = 0; i < size; i++) { 
     String key = parcel.readString(); 
     String value = parcel.readString(); 
     map.put(key, value); 
    } 

    return map; 


    } 

} 

我得到parcelable obj中的onCreateView方法中:

GetSalesItemsRs mGetSalesItemsRs = getArguments().getParcelable(KEY_PARCEL); 
+0

什么AdsObj? – lelloman

+0

这是一个完全类似于“SaleCoinItem”的对象 - 与此用例无关 – Choletski

+0

MapParcelable呢? – lelloman

回答

1

我认为问题是,如果地图为空你不写尺寸领域的包裹,但是当你阅读它总是读取尺寸字段,并可能最终读取一些随机值。所以,或者您更改代码

if (map != null) { 
    out.writeInt(map.size()); 
    for (Map.Entry<String, String> entry : map.entrySet()) { 
     out.writeString(entry.getKey()); 
     out.writeString(entry.getValue()); 
    } 
}else{ 
    out.writeInt(0); 
} 

,你将永远不会得到一个空值重新创建类时,或者创建另一个布尔场“hasMap”,总是写一个

+0

是的,就是这样,你的解决方案正在工作。在此期间,我发现了另一种方法,使用序列化的地图;) – Choletski

+0

我通常只使用此[AS插件](https://github.com/mcharmas/android-parcelable-intellij-plugin)来实现Parcelable,它非常方便 – lelloman