Android Parcel Unmarshalling未知类型代码

时间:2015-03-10 15:48:59

标签: android parcel

好吧,我的问题肯定与其他问题不同。

这是我的写法:

public Folder(Parcel in, ClassLoader loader) {
    id = in.readInt();
    persistentId = in.readString();
    folderUri = new FolderUri((Uri) in.readParcelable(loader));
    name = in.readString();
    capabilities = in.readInt();
    // 1 for true, 0 for false.
    hasChildren = in.readInt() == 1;
    syncWindow = in.readInt();
    conversationListUri = in.readParcelable(loader);
    childFoldersListUri = in.readParcelable(loader);
    unseenCount = in.readInt();
    unreadCount = in.readInt();
    totalCount = in.readInt();
    refreshUri = in.readParcelable(loader);
    syncStatus = in.readInt();
    lastSyncResult = in.readInt();
    type = in.readInt();
    iconResId = in.readInt();
    notificationIconResId = in.readInt();
    bgColor = in.readString();
    fgColor = in.readString();
    if (bgColor != null) {
        bgColorInt = Integer.parseInt(bgColor);
    }
    if (fgColor != null) {
        fgColorInt = Integer.parseInt(fgColor);
    }
    loadMoreUri = in.readParcelable(loader);
    hierarchicalDesc = in.readString();
    parent = in.readParcelable(loader);
    lastMessageTimestamp = in.readLong();
    notificationUri = in.readParcelable(loader);
    updatedCountUri = in.readParcelable(loader);
    unreadSenders = in.readString();
}

这是我的写法:

public void writeToParcel(Parcel dest, int flags) {
    dest.writeInt(id);
    dest.writeString(persistentId);
    dest.writeParcelable(folderUri != null ? folderUri.fullUri : null, 0);
    dest.writeString(name);
    dest.writeInt(capabilities);
    // 1 for true, 0 for false.
    dest.writeInt(hasChildren ? 1 : 0);
    dest.writeInt(syncWindow);
    dest.writeParcelable(conversationListUri, 0);
    dest.writeParcelable(childFoldersListUri, 0);
    dest.writeInt(unseenCount);
    dest.writeInt(unreadCount);
    dest.writeInt(totalCount);
    dest.writeParcelable(refreshUri, 0);
    dest.writeInt(syncStatus);
    dest.writeInt(lastSyncResult);
    dest.writeInt(type);
    dest.writeInt(iconResId);
    dest.writeInt(notificationIconResId);
    dest.writeString(bgColor);
    dest.writeString(fgColor);
    dest.writeParcelable(loadMoreUri, 0);
    dest.writeString(hierarchicalDesc);
    dest.writeParcelable(parent, 0);
    dest.writeLong(lastMessageTimestamp);
    dest.writeParcelable(notificationUri, 0);
    dest.writeParcelable(updatedCountUri, 0);
    dest.writeString(unreadSenders);
}

这完美无缺。如果我DARE更改writeToParcel()方法中的任何内容的顺序或添加一个变量,并相应地从parcel方法(即上面的构造函数)中读取相应的更改,我得到上述错误。我实际上无法改变它或Android barfs。

现在这里变得奇怪了。如果我重新启动设备,那么不会再崩溃,也不会有异常。没有代码更改,只需重新启动。这让我相信Android正在缓存我的包裹并完全无视我写入包裹的内容。我进入调试模式并在我的writeToParcel()方法中设置断点,我可以看到它正在执行每一行,但是当它从我的包裹中读取时,它仍然认为订单是以前的。因此,如果我用writeString()交换writeInt()的行并在我的构造函数中进行更改,那么在读取它时仍然认为Int应该是String所在的位置。 WTF。有人请告诉我这是Android中的一个已知错误。就像我说的,重新启动修复了这个问题。

这是我做分区的地方。我基本上创建了一个PendingIntent,它在解除通知时被触发。

final Intent cancelNotificationIntent = new Intent(INTENT_ACTION);
cancelNotificationIntent.putExtra(Utils.EXTRA_FOLDER, folder);
notification.setDeleteIntent(PendingIntent.getService(context, notificationId, cancelNotificationIntent, 0));

这是我取消选择的地方:

final Folder folder = intent.getParcelableExtra(Utils.EXTRA_FOLDER);

没什么特别的。救命?如果有帮助,我会在Android 4.3和4.4上重现这一点。

1 个答案:

答案 0 :(得分:2)

好的,我的问题原来是一个缓存的PendingIntent。

final Intent cancelNotificationIntent = new Intent(INTENT_ACTION);
cancelNotificationIntent.putExtra(Utils.EXTRA_FOLDER, folder); // This is the parceled object
notification.setDeleteIntent(PendingIntent.getService(context, notificationId, cancelNotificationIntent, 0));

PendingIntent.getService()在为标志传递0时将继续使用相同的PendingIntent一遍又一遍地完全忽略我写入cancelNotificationIntent的任何内容。我通过将其更改为:

来修复它
notification.setDeleteIntent(PendingIntent.getService(context, notificationId, cancelNotificationIntent, PendingIntent.FLAG_UPDATE_CURRENT));

我仍然不明白为什么PendingIntent.getService()即使在应用程序升级后仍继续返回缓存的Intent(即adb install -r app.apk)。如果应用程序被杀死或重新安装,PendingIntent将会消失但是没有。 Android缓存无限期地使用PI,直到您重新启动设备。

希望这有助于其他人。