ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

android – 通过IPC将对象列表从服务传递到活动时,Parcelable项目消失了

2019-09-03 02:23:45  阅读:113  来源: 互联网

标签:parcelable android android-service


我正在编写一个运行非本地服务的Android应用程序,以便从互联网上获取数据.我有一个绑定到所述服务的活动,并检索Order对象列表以显示它们.

将列表从服务传递到活动时似乎出现了问题.虽然这对我来说似乎很简单.

The Problem

All the items in the list, but the item at index 1, are null values.

调试显示服务函数具有正确的列表并返回正确的列表:

这是返回列表的服务中的函数:

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类添加了代码:

public class 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);
    }
}

}

有什么指针吗?

如果您需要,请随时询问具体信息!

解决方法:

问题似乎是由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);
        }
    }
}

标签:parcelable,android,android-service
来源: https://codeday.me/bug/20190903/1794975.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有