【问题标题】:android parcelable loss objectandroid 可打包损失对象
【发布时间】:2020-03-04 18:58:47
【问题描述】:

我在活动之间无法到达 parcelable 时遇到问题。当我在将它发送到另一个活动之前检查对象时,它看起来很好,但在收到它之后,我只能看到一个奇怪的 id,其余字段为空。为什么会这样?也许我这样做的方式是错误的?最好看一下代码部分:

这是可打包的对象:

@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)}]

我也尝试过使对象 Track 可包裹,但效果是一样的。 请帮我解决这个问题。我不明白出了什么问题。

【问题讨论】:

    标签: android object parcelable


    【解决方案1】:

    在实现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();
    }
    

    这里你写的是一个long,然后是一个string,然后是一个map。但是您正在读取一个字节,然后有条件地读取一个 long,然后是一个字符串。您永远不会读回地图,也永远不会写出您的 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();
    }
    

    【讨论】:

    • 谢谢,问题自然解决了。我很愚蠢。再次感谢!
    猜你喜欢
    • 1970-01-01
    • 2013-11-26
    • 2014-10-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-17
    相关资源
    最近更新 更多