我在拆包/读取Parcelable时遇到问题,它具有两个麻烦的属性,即List类型的List,包含Byte数组的列表以及包含String的List,错误是解组未知类型代码。< / strong>
The Parcelable class is a subclass of parent class Message, see below:
package x.y.z.InboxManager;
import android.os.Parcel;
import android.os.Parcelable;
import android.support.annotation.NonNull;
import java.util.Objects;
import x.y.z.Application.XXXApp;
public class Message implements Parcelable{
private static String TAG = "Message";
//client_id (same as wam_id) - String/text – Id of the JAMS unit
private String wam_id= null;
//severity level (Optional) currently not used
private String level = null;
//message - String/text – if topic = “EMERGENCY” then value {Alias possibly having life threating emergency!} else nothing or user provided
private String message = null;
private String image_id = null;
//topic - String/text – “EMERGENCY” OR "ALERT"
private String topic = null;
// time_of_arrival_in_milli_secs_from_epoch -Long/numerical- time of message arrival in milliseconds from epoch based receivers device time
private long timeofArrivalInNanoSecsFromEpoch = 0L;
//viewed - int/numerical - 0 or 1
private int viewed = 0;
//image_data - byte/blob - binary data of the image (all images are assumed to be PNG)
private byte [] imageData = null;
//client alias - String/text – Alias or friendly name associated with clientId
private String clientAlias;
//sql table related attributes
public static String TABLE_NAME="ALERT_MESSAGE";
//COLUMN_NAME_TIME_OF_ARRIVAL will be the primary key
public static String COLUMN_NAME_TIME_OF_ARRIVAL="TIME_OF_ARRIVAL";
public static String COLUMN_NAME_WAM_ID="WAM_ID";
public static String COLUMN_NAME_LEVEL="LEVEL";
public static String COLUMN_NAME_MESSAGE="MESSAGE";
public static String COLUMN_NAME_IMAGE_ID="IMAGE_ID";
public static String COLUMN_NAME_TOPIC="TOPIC";
public static String COLUMN_NAME_VIEWED="VIEWED";
public static String COLUMN__NAME_IMAGE_DATA="IMAGE_DATA";
//SQL
public static final String SQL_CREATE_ENTRIES =
"create table " + Message.TABLE_NAME + " ( "+ Message.COLUMN_NAME_TIME_OF_ARRIVAL + " INTEGER PRIMARY KEY," +
Message.COLUMN_NAME_WAM_ID + " TEXT," +
Message.COLUMN_NAME_LEVEL + " TEXT," +
Message.COLUMN_NAME_MESSAGE + " TEXT," +
Message.COLUMN_NAME_IMAGE_ID + " TEXT," +
Message.COLUMN_NAME_TOPIC + " TEXT,"+
Message.COLUMN_NAME_VIEWED + " BOOLEAN NOT NULL CHECK ( "+ Message.COLUMN_NAME_VIEWED+" IN (0,1))," +
Message.COLUMN__NAME_IMAGE_DATA + " BLOB)";
public static final String SQL_DROP_TABLE_ENTRIES = "DROP TABLE IF EXISTS "+ Message.TABLE_NAME;
private GetImagDataFromUrlTask getImageTask = null;
public void downloadImage()
{
getImageTask = new GetImagDataFromUrlTask(XXXApp.getContext());
getImageTask.execute(this);
}
public void cancelImageDownload()
{
if (getImageTask!=null) {
getImageTask.cancel(true);
}
}
public Message() {
}
public Message(String wam_id, String level, String message, String image_id, long timeofArrivalInNanoSecsFromEpoch) {
this.wam_id = wam_id;
this.level = level;
this.message = message;
this.image_id = image_id;
this. timeofArrivalInNanoSecsFromEpoch = timeofArrivalInNanoSecsFromEpoch;
}
public Message(Parcel in)
{
this.wam_id = in.readString();
this.level = in.readString();
this.message = in.readString();
this.image_id = in.readString();
this.timeofArrivalInNanoSecsFromEpoch = in.readLong();
if (this.imageData!=null) {
in.readByteArray(this.imageData);
}
}
public String getWam_id() {
return wam_id;
}
public void setWam_id(String wam_id) {
this.wam_id = wam_id;
}
public String getLevel() {
return level;
}
public void setLevel(String level) {
this.level = level;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public String getImage_id() {
return image_id;
}
public void setImage_id(String image_id) {
this.image_id = image_id;
}
public long getTimeofArrivalInMilliSecsFromEpoch() {
return timeofArrivalInNanoSecsFromEpoch;
}
public void setTimeofArrivalInMilliSecsFromEpoch(long timeofArrivalInNanoSecsFromEpoch) {
this.timeofArrivalInNanoSecsFromEpoch = timeofArrivalInNanoSecsFromEpoch;
}
public String getTopic() {
return topic;
}
public void setTopic(String topic) {
this.topic = topic;
}
public int getViewed() {
return viewed;
}
public void setViewed(int viewed) {
this.viewed = viewed;
}
public byte[] getImageData() {
return imageData;
}
public void setImageData(byte[] imageData) {
this.imageData = imageData;
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(this.wam_id);
dest.writeString(this.level);
dest.writeString(this.message);
dest.writeString(this.image_id);
dest.writeLong(this.timeofArrivalInNanoSecsFromEpoch);
dest.writeByteArray(imageData);
}
public static final Parcelable.Creator<Message> CREATOR= new Parcelable.Creator<Message>() {
@Override
public Message createFromParcel(Parcel source) {
// TODO Auto-generated method stub
return new Message(source); //using parcelable constructor
}
@Override
public Message[] newArray(int size) {
return new Message[size];
}
};
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Message that = (Message) o;
return timeofArrivalInNanoSecsFromEpoch == that.timeofArrivalInNanoSecsFromEpoch;
//TODO: update equivalency
/*if (message!=null) {
return timeofArrivalInNanoSecsFromEpoch == that.timeofArrivalInNanoSecsFromEpoch && message.equalsIgnoreCase(that.message);
}
else
{
return timeofArrivalInNanoSecsFromEpoch == that.timeofArrivalInNanoSecsFromEpoch && wam_id.equalsIgnoreCase(that.wam_id);
}*/
}
@Override
public String toString() {
return "Message{" +
"wam_id='" + wam_id + '\'' +
", level='" + level + '\'' +
", message='" + message + '\'' +
", image_id='" + image_id + '\'' +
", topic='" + topic + '\'' +
", timeofArrivalInMillisecs=" + timeofArrivalInNanoSecsFromEpoch +
", viewed=" + viewed +
'}';
}
@Override
public int hashCode() {
return Objects.hash(timeofArrivalInNanoSecsFromEpoch);
}
}
该错误发生在“紧急”子类中,请参见下文,请参见属性:
in.readList(extras,Byte[].class.getClassLoader());
in.readList(extrasFormat,Formats.ExtrasFormat.class.getClassLoader());
整个课程:
package x.y.z.InboxManager;
import android.os.Parcel;
import android.os.Parcelable;
import java.util.ArrayList;
import java.util.List;
public class Emergency extends Message implements Parcelable {
private String clientAlias;
private String topic;
private Long timeOfPublish;
private Double lat;
private Double lon;
private List<Byte[]> extras = new ArrayList<Byte[]>();
private List<Formats.ExtrasFormat> extrasFormat = new ArrayList<Formats.ExtrasFormat>();
public Emergency()
{
}
public Emergency(Parcel in)
{
//super(in.readString(),in.readString(),in.readString(),in.readString(),in.readLong());
super(in);
this.clientAlias = in.readString();
this.topic = in.readString();
this.timeOfPublish = in.readLong();
this.lat = in.readDouble();
this.lon = in.readDouble();
super.setViewed(in.readInt());
in.readList(extras,Byte[].class.getClassLoader());
in.readList(extrasFormat,Formats.ExtrasFormat.class.getClassLoader());
}
public Emergency(String clientId,String level,String message,String imageId,Long timeOfArrival,String clientAlias, String topic,Long timeOfPublish,Double lat, Double lon,int viewed,List<Byte[]> extras,List<Formats.ExtrasFormat> extrasFormats)
{
super(clientId,level,message,imageId,timeOfArrival);
super.setViewed(viewed);
this.clientAlias = clientAlias;
this.topic = topic;
this.timeOfPublish = timeOfPublish;
this.lat = lat;
this.lon = lon;
this.extras = extras;
this.extrasFormat = extrasFormats;
}
public String getClientAlias() {
return clientAlias;
}
@Override
public String getTopic() {
return topic;
}
public Long getTimeOfPublish() {
return timeOfPublish;
}
public Double getLat() {
return lat;
}
public Double getLon() {
return lon;
}
public List<Byte[]> getExtras() {
return extras;
}
public List<Formats.ExtrasFormat> getExtrasFormat() {
return extrasFormat;
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
super.writeToParcel(dest,flags);
dest.writeString(this.clientAlias);
dest.writeString(this.topic);
dest.writeLong( this.timeOfPublish);
dest.writeDouble(this.lat);
dest.writeDouble(this.lon);
dest.writeInt(this.getViewed());
dest.writeList(extras);
dest.writeList(extrasFormat);
}
public static final Parcelable.Creator<Emergency> CREATOR= new Parcelable.Creator<Emergency>() {
@Override
public Emergency createFromParcel(Parcel source) {
// TODO Auto-generated method stub
return new Emergency(source); //using parcelable constructor
}
@Override
public Emergency[] newArray(int size) {
return new Emergency[size];
}
};
}
异常/错误日志如下:
Process: x.y.z, PID: 14292
java.lang.RuntimeException: Unable to start service x.y.z.services.MqttBrokerService@3a0f1bd with Intent { act=x.y.z.action.EMERGENCY_MESSAGE cmp=x.y.z/.services.MqttBrokerService (has extras) }: java.lang.RuntimeException: Parcel android.os.Parcel@748514: Unmarshalling unknown type code 6357111 at offset 408
at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:3347)
at android.app.ActivityThread.-wrap21(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1586)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6145)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)
Caused by: java.lang.RuntimeException: Parcel android.os.Parcel@748514: Unmarshalling unknown type code 6357111 at offset 408
at android.os.Parcel.readValue(Parcel.java:2444)
at android.os.Parcel.readListInternal(Parcel.java:2793)
at android.os.Parcel.readList(Parcel.java:1836)
at x.y.z.InboxManager.Emergency.<init>(Emergency.java:65)
at x.y.z.InboxManager.Emergency$1.createFromParcel(Emergency.java:139)
at x.y.z.InboxManager.Emergency$1.createFromParcel(Emergency.java:134)
如何正确将其编组和解组到列表?
谢谢
答案 0 :(得分:1)
在超类中,这看起来是错误的:
public Message(Parcel in) { ... if (this.imageData!=null) { in.readByteArray(this.imageData); } } @Override public void writeToParcel(Parcel dest, int flags) { ... dest.writeByteArray(imageData); }
相对而言,我可以肯定this.imageData
始终是null
,这意味着writeToParcel()
中没有匹配的“读取”和“写入” 。相反,您应该使用createByteArray()
:
public Message(Parcel in)
{
...
this.imageData = in.createByteArray();
}
然后我们必须考虑子类:
public Emergency(Parcel in) { ... in.readList(extrasFormat,Formats.ExtrasFormat.class.getClassLoader()); } @Override public void writeToParcel(Parcel dest, int flags) { ... dest.writeList(extrasFormat); }
Formats.ExtrasFormat
是否实现可打包或可序列化?如果没有,我不相信这会起作用。如果确实如此,那么只需修复超类即可。