android 可分包损失对象
android parcelable loss object
我在活动之间达成可分割性时遇到问题。当我在将对象发送到另一个 activity 之前检查该对象时,它看起来不错,但在收到它之后我只能看到一个奇怪的 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)}]
我也试过让 Object Track parcelable 但效果是一样的。
请帮我解决这个问题。我不明白哪里出了问题。
实施 Parcelable
时,您 必须保证 您 "write" 的所有内容都与相应的 "read" 调用完全匹配。让我们看看您的代码:
@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();
}
我在活动之间达成可分割性时遇到问题。当我在将对象发送到另一个 activity 之前检查该对象时,它看起来不错,但在收到它之后我只能看到一个奇怪的 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)}]
我也试过让 Object Track parcelable 但效果是一样的。 请帮我解决这个问题。我不明白哪里出了问题。
实施 Parcelable
时,您 必须保证 您 "write" 的所有内容都与相应的 "read" 调用完全匹配。让我们看看您的代码:
@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();
}