Android Parcel Unmarshalling неизвестный код типа
Хорошо, мой, безусловно, отличается от всех других вопросов, задаваемых с этой же проблемой
Вот мой метод записи:
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);
}
Это прекрасно работает без проблем. Если я осмелюсь изменить порядок чего-либо в моем методе writeToParcel() или добавлю переменную и, соответственно, внесу соответствующее изменение в метод чтения из посылки (т.е. конструктор выше), я получу вышеуказанную ошибку. Я буквально не могу внести изменения в него или Android Barfs.
Теперь вот где это становится странным. Если я перезагружаю устройство, то больше нет сбоя, нет больше исключения. Без изменения кода, просто перезагрузка. Это заставляет меня поверить, что Android кэширует мою посылку и полностью игнорирует то, что я пишу в посылку. Я вхожу в режим отладки и устанавливаю точку останова в своем методе writeToParcel(), и я вижу, что он выполняет каждую строку, но когда он идет на чтение из моей посылки, он все еще думает, что порядок такой, каким он был раньше. Поэтому, если я поменяю строки для writeInt() с writeString() и внесу изменения в мой конструктор, при чтении он все еще думает, что 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 ответ
Итак, моя проблема оказалась в кэше 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 бесконечно, пока вы не перезагрузите устройство.
Надеюсь, это поможет кому-то еще.