android объект убытка от продажи - PullRequest
1 голос
/ 04 марта 2020

У меня проблемы с достижением посылки между действиями. Когда я проверяю объект перед отправкой в ​​другое действие, он выглядит нормально, но после его получения я вижу только странный идентификатор, а остальные поля обнуляются. Почему это происходит? Может быть, то, как я это делаю, неправильно? Лучше всего, вы посмотрите на части кода:

Это подлежащий продаже объект:

@Data
@NoArgsConstructor
public class Scene implements Parcelable
{
    private Long id;
    private String name;
    private Light light;
    private Track effect;
    private Track music;
    private Track ambience;

    protected Scene(Parcel in)
    {
        if (in.readByte() == 0) { id = null; } else { id = in.readLong(); }
        name = in.readString();
    }

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

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

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

    @Override
    public void writeToParcel(Parcel dest, int flags)
    {
        Map<String, Track> audio = new HashMap<>();
        audio.put(Tags.EFFECT.value(), effect);
        audio.put(Tags.MUSIC.value(), music);
        audio.put(Tags.AMBIENCE.value(), ambience);

        dest.writeLong(id);
        dest.writeString(name);
        dest.writeMap(audio);
    }
}

Сцена имеет карту, содержащую аудиофайлы. Они сериализуемы (или лучше, и разлагаемы?) Ничего сложного, простой POJO:

@Data
public class Track implements Serializable
{
    private Long id;
    private String name;
    private String path;
    private Long duration;
    private String artist;
    private String tag;
}

И, наконец, как я получаю объект:

public class AudioPlayer extends Service
[...]
    public int onStartCommand(Intent intent, int flags, int startId)
    {
        Scene scene = intent.getParcelableExtra("scene");
       [...]
    }
}

Когда я проверяю объект по intent.setParcelableExtra () я получаю это:

Scene(id=7, name=test, light=null, effect=Track(id=10, name=file.mp3, path=/some/path/file.mp3, duration=13662, artist=null, tag=effect), music=Track(id=11, name=other_file.mp3, path=/some/other/path/other_file.mp3, duration=189492, artist=null, tag=music), ambience=Track(id=12, name=another_other_file.mp3, path=/some/another/other/path/another_other_file.mp3, duration=10109, artist=null, tag=ambience))

Когда я проверяю объект по intent.getParcelableExtra (), я получаю это:

Bundle[{scene=Scene(id=17179869184, name=null, light=null, effect=null, music=null, ambience=null)}]

Я пытался также сделать Объект Трек можно продать, но эффект был тот же. Пожалуйста, помогите мне решить эту проблему. Я не понимаю, что идет не так.

1 Ответ

2 голосов
/ 04 марта 2020

При реализации Parcelable вы должны гарантировать , что все, что вы «пишете», точно соответствует соответствующему вызову «чтения». Давайте посмотрим на ваш код:

@Override
public void writeToParcel(Parcel dest, int flags)
{
    Map<String, Track> audio = new HashMap<>();
    audio.put(Tags.EFFECT.value(), effect);
    audio.put(Tags.MUSIC.value(), music);
    audio.put(Tags.AMBIENCE.value(), ambience);

    dest.writeLong(id);
    dest.writeString(name);
    dest.writeMap(audio);
}

protected Scene(Parcel in)
{
    if (in.readByte() == 0) { id = null; } else { id = in.readLong(); }
    name = in.readString();
}

Здесь вы пишете длинную строку, затем строку, а затем карту. Но вы читаете байт, затем условно длинный, а затем строку. Вы никогда не читаете карту обратно и никогда не пишете свое значение light.

Эти проблемы необходимо будет решить. Вот как это может выглядеть:

@Override
public void writeToParcel(Parcel dest, int flags)
{
    if (id != null) {
        dest.writeInt(1);
        dest.writeLong(id);
    } else {
        dest.writeInt(0);
    }
    dest.writeString(name);
    dest.writeSerializable(light);
    dest.writeSerializable(effect);
    dest.writeSerializable(music);
    dest.writeSerializable(ambience);
}

protected Scene(Parcel in)
{
    if (in.readInt() == 1) { 
        this.id = in.readLong();
    } else { 
        this.id = null;
    }
    this.name = in.readString();
    this.light = (Light) in.readSerializable();
    this.effect = (Track) in.readSerializable();
    this.music = (Track) in.readSerializable();
    this.ambience = (Track) in.readSerializable();
}
...