我看不出错误,我已经有很长一段时间没遇到这个问题了...如果重新创建了我的parcelable类会崩溃,但我找不到问题......
我在第一个代码块中标记了创建以下异常的行:java.lang.ArrayIndexOutOfBoundsException: length=5; index=5
简短代码
private Set<ContactType> mMatchesDataLoaded = new HashSet<ContactType>();
保存集
dest.writeInt(mMatchesDataLoaded.size());
Iterator<ContactType> it = mMatchesDataLoaded.iterator();
while (it.hasNext())
dest.writeInt(it.next().ordinal());
阅读
int count = source.readInt();
for (int i = 0; i < count; i++)
// ---------------------------------------------------------------------------
// next line produces EXCEPTION!!! java.lang.ArrayIndexOutOfBoundsException: length=5; index=5
// ---------------------------------------------------------------------------
mMatchesDataLoaded.add(ContactType.values()[source.readInt()]);
完整代码
我看不出任何问题,或者更确切地说问题出在哪里......
public class ContactPhone implements Parcelable
{
public static enum ContactType
{
WhatsApp,
Viber,
GooglePlus,
Twitter,
Instagram
}
private boolean mIsUserProfile = false;
private boolean mHasImage;
private int mId;
private long mRawId;
private String mName = null;
private List<PhoneNumber> mNumbers = new ArrayList<PhoneNumber>();
private DBPhoneContact mDBContact = null;
private Set<ContactType> mMatchesDataLoaded = new HashSet<ContactType>();
private HashMap<ContactType, List<BaseMatchContact>> mMatchesData = new HashMap<ContactType, List<BaseMatchContact>>();
// ----------------------
// Parcelable
// ----------------------
@Override
public void writeToParcel(Parcel dest, int flags)
{
ParcelBundleUtils.writeBoolean(dest, mIsUserProfile);
ParcelBundleUtils.writeBoolean(dest, mHasImage);
ParcelBundleUtils.writeIntegerNullSafe(dest, mId);
ParcelBundleUtils.writeLongNullSafe(dest, mRawId);
ParcelBundleUtils.writeStringNullSafe(dest, mName);
dest.writeList(mNumbers);
ParcelBundleUtils.writeLongNullSafe(dest, mDBContact != null ? mDBContact.getId() : null);
// save set
dest.writeInt(mMatchesDataLoaded.size());
Iterator<ContactType> it = mMatchesDataLoaded.iterator();
while (it.hasNext())
dest.writeInt(it.next().ordinal());
// save HashMap
dest.writeInt(mMatchesData.size());
for (Map.Entry<ContactType, List<BaseMatchContact>> entry : mMatchesData.entrySet())
{
dest.writeInt(entry.getKey().ordinal());
dest.writeInt(entry.getValue().size());
for (int i = 0; i < entry.getValue().size(); i++)
dest.writeParcelable(entry.getValue().get(i), 0);
}
}
public void readFromParcel(Parcel source)
{
mIsUserProfile = ParcelBundleUtils.readBoolean(source);
mHasImage = ParcelBundleUtils.readBoolean(source);
mId = ParcelBundleUtils.readIntegerNullSafe(source);
mRawId = ParcelBundleUtils.readLongNullSafe(source);
mName = ParcelBundleUtils.readStringNullSafe(source);
source.readList(mNumbers, PhoneNumber.class.getClassLoader());
Long id = ParcelBundleUtils.readLongNullSafe(source);
mDBContact = null;
if (id != null)
mDBContact = MainApp.getDS().getDBPhoneContactDao().load(id);
// read set
int count = source.readInt();
for (int i = 0; i < count; i++)
// ---------------------------------------------------------------------------
// next line produces EXCEPTION!!! java.lang.ArrayIndexOutOfBoundsException: length=5; index=5
// ---------------------------------------------------------------------------
mMatchesDataLoaded.add(ContactType.values()[source.readInt()]);
// read HashMap
count = source.readInt();
for (int i = 0; i < count; i++)
{
ContactType type = ContactType.values()[source.readInt()];
Class<?> clazz = BaseDef.getMatchClass(type);
// L.d(this, "Classloader: " + clazz.getName() + " type: " + type.name());
int size = source.readInt();
List<BaseMatchContact> list = new ArrayList<BaseMatchContact>();
for (int j = 0; j < size; j++)
list.add((BaseMatchContact) source.readParcelable(clazz.getClassLoader()));
mMatchesData.put(type, list);
}
}
}
PhoneNumber
类实现了parcelable,非常简单,读/写如下:
@Override
public void writeToParcel(Parcel dest, int flags)
{
ParcelBundleUtils.writeStringNullSafe(dest, mName);
ParcelBundleUtils.writeStringNullSafe(dest, mNormNumber);
ParcelBundleUtils.writeStringNullSafe(dest, mNumber);
}
public void readFromParcel(Parcel source)
{
mName = ParcelBundleUtils.readStringNullSafe(source);
mNormNumber = ParcelBundleUtils.readStringNullSafe(source);
mNumber = ParcelBundleUtils.readStringNullSafe(source);
}
这是我的助手功能:
public static void writeBoolean(Parcel p, boolean b)
{
p.writeByte((byte) (b ? 1 : 0));
}
public static boolean readBoolean(Parcel p)
{
return p.readByte() == 1;
}
public static void writeStringNullSafe(Parcel p, String s)
{
p.writeByte((byte) (s != null ? 1 : 0));
if (s != null)
p.writeString(s);
}
public static void writeIntegerNullSafe(Parcel p, Integer i)
{
p.writeByte((byte) (i != null ? 1 : 0));
if (i != null)
p.writeInt(i);
}
public static void writeLongNullSafe(Parcel p, Long l)
{
p.writeByte((byte) (l != null ? 1 : 0));
if (l != null)
p.writeLong(l);
}
public static void writeDoubleNullSafe(Parcel p, Double d)
{
p.writeByte((byte) (d != null ? 1 : 0));
if (d != null)
p.writeDouble(d);
}
public static void writeParcelableNullSafe(Parcel p, Parcelable d, int flags)
{
p.writeByte((byte) (d != null ? 1 : 0));
if (d != null)
p.writeParcelable(d, flags);
}
public static String readStringNullSafe(Parcel p)
{
boolean isPresent = p.readByte() == 1;
return isPresent ? p.readString() : null;
}
public static Integer readIntegerNullSafe(Parcel p)
{
boolean isPresent = p.readByte() == 1;
return isPresent ? p.readInt() : null;
}
public static Long readLongNullSafe(Parcel p)
{
boolean isPresent = p.readByte() == 1;
return isPresent ? p.readLong() : null;
}
public static Double readDoubleNullSafe(Parcel p)
{
boolean isPresent = p.readByte() == 1;
return isPresent ? p.readDouble() : null;
}
@SuppressWarnings("unchecked")
public static <T extends Parcelable> T readParcelableNullSafe(Parcel p, ClassLoader classLoader)
{
boolean isPresent = p.readByte() == 1;
return isPresent ? (T) p.readParcelable(classLoader) : null;
}
答案 0 :(得分:1)
int count = source.readInt(); // index is raised + 1
for (int i = 0; i < count; i++)
mMatchesDataLoaded.add(ContactType.values()[source.readInt()]); // index is raised by 1, starting with 1!
你从0循环到4,但是source.readInt()已被调用一次,所以你总共调用了5次。
答案 1 :(得分:0)
ContactType包含5个值,从索引0到索引4.您正在尝试访问索引5,该索引不存在。
mMatchesDataLoaded.add(ContactType.values()[source.readInt()]);
source.readInt()给你一个5,试着弄清楚,为什么它包含这个值。
我的猜测是writeToParcel写了这个5,尝试检查mMatchesDataLoaded,它可能包含一些额外的不需要的数据。