Предметы, подлежащие продаже, исчезают при передаче списка объектов из сервиса в активность через IPC - PullRequest
3 голосов
/ 25 августа 2011

Я пишу приложение для Android, которое запускает нелокальную службу для получения данных из Интернета.У меня есть действие, которое привязывается к указанному сервису и извлекает список объектов Order, чтобы отобразить их.

Что-то идет не так при передаче списка из сервиса в действие.Хотя это кажется довольно простым для меня.

Проблема

Все элементы в списке, кроме элемента с индексом 1, имеют нулевые значения.

Debug view of the received list from activity

Отладка показывает, что сервисная функция имеет правильный список, а также возвращает правильный список:

Debug view of the list to send from the service

Это функция в сервисе, котораявозвращает список:

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;
    }
}

Это функция в Деятельности, которая вызывает службу и получает список (где 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 есть несколько.

Редактирование: Добавлена ​​реализация Parcelable для класса Order (упрощается путем удаления большинства примитивных свойств):

/*
* 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 расширяет 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);
    }
}

}

Есть указатели?

Пожалуйста, не стесняйтесь спрашивать конкретную информацию, если она вам нужна!

Ответы [ 4 ]

3 голосов
/ 26 августа 2011

Кажется, проблема вызвана двумя целочисленными свойствами класса Order.Один из них никогда не инициализируется и поэтому является нулевым.При записи этого в Посылку происходит сбой, что приводит к сбою всей функции и вызывает появление пустых значений в результирующем списке.Странно, что это не вызывает никаких исключений.

Изменение моих свойств Integer обратно на int устранило проблему (потому что int никогда не равен null).Поскольку мне действительно нужно было поддерживать тип Integer, я исправил его, передав нулевые значения в посылку как значение -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 голос
/ 25 августа 2011

Вы должны будете предоставить еще немного кода, чтобы быть уверенным, но вы должны убедиться, что каждый объект, который вы хотите передать между вашим сервисом, правильно реализует Parcelable.

ArrayList, например не реализует интерфейс, вам придется расширить его и сделать необходимые сантехнические работы, чтобы он работал.

Пример всего этого здесь.

1 голос
/ 25 августа 2011

Вероятно, это проблема десериализации. Можете ли вы показать нам сериализованный ответ от службы (xml / json)?

0 голосов
/ 26 августа 2011

Попробуйте передать массив Orders.

...