我正在编写一个运行非本地服务的Android应用程序,以便从互联网上获取数据。我有一个绑定到所述服务的活动,并检索Order对象列表以显示它们。
将列表从服务传递到活动时似乎出现了问题。虽然这对我来说似乎很简单。
问题
列表中的所有项目,但索引1处的项目都是空值。
调试显示服务功能具有正确的列表并返回正确的列表:
这是返回列表的服务中的函数:
public List<Order> getOrders() throws RemoteException {
synchronized(service.orders) {
// service.orders returns a hashmap<Integer, Order>
// where the key is the ID of the order
// The function returns a simple list, so we parse to an ArrayList
List<Order> result = new ArrayList<Order>(service.orders.values());
return result;
}
}
这是Activity中调用服务并检索列表的函数(其中api是绑定到服务的结果):
handler.post(new Runnable() {
public void run() {
try {
List<Order> result = api.getOrders();
displayOrders(result);
} catch (Throwable t) {
Log.e(TAG, "Error while updating the UI with orders", t);
}
}
});
这让我感到非常难过,因为我还有一个活动来查看客户和一个返回客户列表的服务功能,并且运行完美。两者之间的主要区别在于Customer没有任何自定义对象属性,而Order有一些。
编辑:为Order类添加了Parcelable实现(通过删除大多数原始属性简化):
/*
* Parcelabe interface implementation
*/
public static final Creator<Order> CREATOR = new Creator<Order>() {
public Order createFromParcel(Parcel source) {
return new Order(source);
}
public Order[] newArray(int size) {
return new Order[size];
}
};
public Order(Parcel source) {
ID = source.readInt();
OrderID = source.readInt();
CustomerID = source.readInt();
TotalAmount = source.readDouble();
TotalProducts = source.readDouble();
OrderDate = source.readString();
InvoiceDate = source.readString();
DeliveryDate = source.readString();
// Custom objects
Customer = source.readParcelable(Customer.class.getClassLoader());
History = new ArrayList<OrderHistory>();
source.readTypedList(History, OrderHistory.CREATOR);
State = source.readParcelable(OrderState.class.getClassLoader());
}
public int describeContents() {
return Order.class.hashCode();
}
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(ID);
dest.writeInt(OrderID);
dest.writeInt(CustomerID);
dest.writeDouble(TotalAmount);
dest.writeDouble(TotalProducts);
dest.writeString(OrderDate);
dest.writeString(InvoiceDate);
dest.writeString(DeliveryDate);
// Custom object
dest.writeParcelable(Customer, flags);
dest.writeParcelable(State, flags);
dest.writeTypedList(History);
}
编辑:为OrderList类添加了代码:
公共类OrderList extends ArrayList实现了Parcelable {
/**
*
*/
private static final long serialVersionUID = 417326483896340670L;
public OrderList() {
}
public OrderList(Parcel in) {
readFromParcel(in);
}
/*
* Parcelabe interface implementation
*/
public OrderList(Collection<Order> values) {
this.addAll(values);
}
@SuppressWarnings("unchecked")
public static final Parcelable.Creator<OrderList> CREATOR = new Parcelable.Creator<OrderList>() {
public OrderList createFromParcel(Parcel in) {
return new OrderList(in);
}
public OrderList[] newArray(int arg0) {
return null;
}
};
private void readFromParcel(Parcel in) {
this.clear();
//First we have to read the list size
int size = in.readInt();
//Reading remember that we wrote first the Name and later the Phone Number.
//Order is fundamental
for (int i = 0; i < size; i++) {
Order o = new Order();
o = in.readParcelable(Order.class.getClassLoader());
this.add(o);
}
}
public int describeContents() {
return 0;
}
public void writeToParcel(Parcel dest, int flags) {
int size = this.size();
// We have to write the list size, we need him recreating the list
dest.writeInt(size);
// We decided arbitrarily to write first the Name and later the Phone Number.
for (int i = 0; i < size; i++) {
Order o = this.get(i);
dest.writeParcelable(o, flags);
}
}
}
任何指针?
如果您需要,请随时询问具体信息!
答案 0 :(得分:3)
问题似乎是由Order类的两个Integer属性引起的。其中一个从未初始化,因此为null。将其写入Parcel时,它会导致整个函数失败,并导致在结果列表中弹出空值。奇怪的是,这不会引发任何例外。
将我的Integer属性更改回int修复了问题(因为int永远不为null)。由于我确实需要维护Integer类型,因此我通过将parcel中的空值作为值-1来修复它。
这归结为:
public class Order implements Parcelable {
public Integer ID;
public Integer OrderID;
public Order(Parcel source) {
ID = source.readInt();
if (ID.intValue() == -1) {
ID = null;
}
OrderID = source.readInt();
if (OrderID.intValue() == -1) {
OrderID = null;
}
}
public void writeToParcel(Parcel dest, int flags) {
if (ID == null) {
dest.writeInt(-1);
} else {
dest.writeInt(ID);
}
if (OrderID == null) {
dest.writeInt(-1);
} else {
dest.writeInt(OrderID);
}
}
}
答案 1 :(得分:1)
这可能是一个反序列化问题。你能告诉我们服务的序列化响应(xml / json)吗?
答案 2 :(得分:1)
您必须提供更多代码才能确定,但您必须确保要在服务之间传输的每个对象都能正确实现Parcelable。
ArrayList for example没有实现接口,你必须扩展它并进行必要的管道才能使它工作。
答案 3 :(得分:0)
尝试传递一系列订单。