尝试从Intent读取额外数据时崩溃

时间:2018-10-26 08:12:26

标签: android android-intent serialization

尝试从传递给服务的Intent中读取其他内容时,我的应用程序崩溃。最奇怪的是,当我忽略我使用的五个附加功能中的任何一个时,它都可以正常工作。 传递的数据的大小不是问题,它在活页夹限制之内。 stacktrace指出了可打包实现中的问题,但是又为什么要从捆绑中删除类似{long的"startPos"使其起作用?

意图创建:

 val startIntent = Intent(context, AudioService::class.java)
        startIntent.putExtra("media", playerMedia) //parcelable
        startIntent.putExtra("statConfig", statConfig) //parcelable
        startIntent.putParcelableArrayListExtra("adverts", ArrayList(adverts))
        startIntent.putExtra("startNow", startNow) //Boolean
        startIntent.putExtra("startPos", startPosition) // Long

从意图中读取:

 val media = intent.getParcelableExtra<PlayerMedia>("media")
    val config = intent.getParcelableExtra<PlayerStatConfig>("statConfig")
    val adverts = intent.getParcelableArrayListExtra<Advert>("adverts")
            ?: mutableListOf<Advert>()
    val startNow = intent.getBooleanExtra("startNow", true)
     val startPosition = intent.getLongExtra("startPos", 0L)

踪迹:

W/ArrayMap: New hash 0 is before end of array hash 103772132 at index 3 key 
java.lang.RuntimeException: here
    at android.util.ArrayMap.append(ArrayMap.java:547)
    at android.os.Parcel.readArrayMapInternal(Parcel.java:3047)
    at android.os.BaseBundle.unparcel(BaseBundle.java:257)
    at android.os.Bundle.getParcelable(Bundle.java:888)
    at android.content.Intent.getParcelableExtra(Intent.java:7075)
    at myapp.audio.AudioService.processIntent(AudioService.kt:153)
    at myapp.audio.AudioService.onStartCommand(AudioService.kt:101)

Caused by: java.lang.RuntimeException: Parcel android.os.Parcel@3e5e678: Unmarshalling unknown type code 97 at offset 2240
    at android.os.Parcel.readValue(Parcel.java:2755)
    at android.os.Parcel.readArrayMapInternal(Parcel.java:3043)
    at android.os.BaseBundle.unparcel(BaseBundle.java:257)
    at android.os.Bundle.getParcelable(Bundle.java:888)
    at android.content.Intent.getParcelableExtra(Intent.java:7075)
    at myapp.audio.AudioService.processIntent(AudioService.kt:153)
    at myapp.audio.AudioService.onStartCommand(AudioService.kt:101)

编辑:PlayerMedia可拆分实现(我相信它在应用程序中的其他地方都有效):

@Override
public void writeToParcel(Parcel dest, int flags) {
    dest.writeString(this.mTitle);
    dest.writeString(this.mDescription);
    dest.writeString(this.mThumbnailUrl);
    dest.writeString(this.mCaptionImageUrl);
    dest.writeString(this.mSubtitlesUri);
    dest.writeString(this.mIncompleteSplUrl);
    dest.writeString(this.mCastUrl);
    dest.writeString(this.mSimpleUrl);
    if(mCustomData!=null){
        dest.writeSerializable(this.mCustomData.getClass());
    } else{
        dest.writeSerializable(this.getClass());
    }

    dest.writeParcelable(this.mCustomData, flags);
    dest.writeSerializable(this.mCustomCastMetadata);
    dest.writeParcelable(this.mProductPlacement, flags);
    dest.writeLong(this.mDuration);
    dest.writeByte(this.mStartNotified ? (byte) 1 : (byte) 0);
    dest.writeByte(this.mInitAutoplay ? (byte) 1 : (byte) 0);
    dest.writeLong(this.mInitPosition);
    dest.writeTypedList(this.mInitAdverts);
    dest.writeByte(this.mLive ? (byte) 1 : (byte) 0);
    dest.writeSerializable(this.mPartHitTimes);
    dest.writeString(mSubtitle);
    dest.writeParcelable(downloadOptions,flags);
    dest.writeLong(mPlayFrom);
    dest.writeLong(mPlayTo);
    dest.writeByte(this.mLimited ? (byte) 1 : (byte) 0);
}

public PlayerMedia(Parcel in) {
    this.mTitle = in.readString();
    this.mDescription = in.readString();
    this.mThumbnailUrl = in.readString();
    this.mCaptionImageUrl = in.readString();
    this.mSubtitlesUri = in.readString();
    this.mIncompleteSplUrl = in.readString();
    this.mCastUrl = in.readString();
    this.mSimpleUrl = in.readString();
    Class clazz = (Class) in.readSerializable();
    this.mCustomData = in.readParcelable( clazz.getClassLoader());
    this.mCustomCastMetadata = (HashMap<String, Object>) in.readSerializable();
    this.mProductPlacement = in.readParcelable(ProductPlacement.class.getClassLoader());
    this.mDuration = in.readLong();
    this.mStartNotified = in.readByte() != 0;
    this.mInitAutoplay = in.readByte() != 0;
    this.mInitPosition = in.readLong();
    this.mInitAdverts = in.createTypedArrayList(Advert.CREATOR);
    this.mLive = in.readByte() != 0;
    this.mPartHitTimes = (HashSet<Integer>) in.readSerializable();
    this.mSubtitle = in.readString();
    this.downloadOptions = in.readParcelable(DownloadOptions.class.getClassLoader());
    this.mPlayFrom = in.readInt();
    this.mPlayTo = in.readInt();
    this.mLimited = in.readByte() != 0;
}

0 个答案:

没有答案