Question

I am working on a project that involves me having to share an array list of objects with all of the activities that make up the application. Until recently I was passing the list between activities by implementing the parcelable interface. An example of this is seen below:

MenuItem class:

ublic class MenuItem implements Parcelable {

private String name;
private double price;
private int qty;
private String info;

public MenuItem(String name, double price) {
    super();
    this.name = name;
    this.price = price;
}
public MenuItem() {
    // TODO Auto-generated constructor stub
}
public String getName() {
    return name;
}
public void setName(String name) {
    this.name = name;
}
public double getPrice() {
    return price;
}
public void setPrice(double price) {
    this.price = price;
}

public int getQty() {
    return qty;
}
public void setQty(int qty) {
    this.qty = qty;
}
public String getInfo() {
    return info;
}
public void setInfo(String info) {
    this.info = info;
}
@Override
public String toString() {
    return name;
}


//Parcelable methods.
public static final Parcelable.Creator<MenuItem> CREATOR = new Parcelable.Creator<MenuItem>() {

    @Override
    public MenuItem createFromParcel(Parcel source) {
        return new MenuItem(source);
    }

    @Override
    public MenuItem[] newArray(int size) {
        return new MenuItem[size];
    }
};

public MenuItem(Parcel source) {
    this();
    readFromParcel(source);
}

private void readFromParcel(Parcel source) {
    name = source.readString();
    price = source.readDouble();
}

@Override
public int describeContents() {
    return 0;
}

@Override
public void writeToParcel(Parcel dest, int flags) {
    dest.writeString(name);
    dest.writeDouble(price);
}

}

Order class - which I would change to be the Singleton (holds list of menu items)

public class Order implements Parcelable {


private int covers;
private int table;
private ArrayList<MenuItem> items;


public Order(){
    super();
    this.items = new ArrayList<MenuItem>();

}

public static final Parcelable.Creator<Order> CREATOR = new Parcelable.Creator<Order>() {

    @Override
    public Order createFromParcel(Parcel source) {
        return new Order(source);
    }

    @Override
    public Order[] newArray(int size) {
        return new Order[size];
    }


};

public Order(int covers, int table) {
    super();
    this.covers = covers;
    this.table = table;
    this.items = new ArrayList<MenuItem>();
}

public int getCovers() {
    return covers;
}

public void setCovers(int covers) {
    this.covers = covers;
}

public int getTable() {
    return table;
}

public void setTable(int table) {
    this.table = table;
}

public ArrayList<MenuItem> getItems() {
    return items;
}

public void setItems(ArrayList<MenuItem> items) {
    this.items = items;
}

//add to order
public void addToOrder(MenuItem m){
    items.add(m);
}

//remove from order
public void removeFromOrder(MenuItem m){
    items.remove(m);
}

public Order(Parcel source) {
    this();
    readFromParcel(source);
}

@Override
public int describeContents() {
    // TODO Auto-generated method stub
    return 0;
}

@Override
public void writeToParcel(Parcel dest, int flags) {
    // TODO Auto-generated method stub
    dest.writeInt(covers);
    dest.writeInt(table);
    dest.writeTypedList(items);

}

private  void readFromParcel(Parcel source) {
    // TODO Auto-generated method stub
    covers = source.readInt();
    table = source.readInt();
    items = new ArrayList<MenuItem>();
    source.readTypedList(items,  MenuItem.CREATOR);

}

}

This is how I pass the data between activities:

myOrderBtn.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {
            Toast.makeText(v.getContext(), "myOrderBtn", Toast.LENGTH_SHORT).show();
            Intent i = new Intent(v.getContext(), ViewOrderActivity.class);
            i.putExtra("data", order);
            if(!saved){
            saveOrderState();
            }
            startActivity(i);

        }
    });

and retrieve this way:

public void getOrderData(){
    Intent i = getIntent();
    if(i != null && i.hasExtra("data")){
        order = i.getParcelableExtra("data");
        Toast.makeText(this.getApplicationContext(), "STARTERS recieved order object, covers: " + order.getCovers() + " table no: " + order.getTable() + " order size: " + order.getItems().size(), Toast.LENGTH_SHORT).show();

        if(order.getItems().size() == 0){
            //Toast.makeText(this.getApplicationContext(), "No items added to your order...", Toast.LENGTH_SHORT).show();
        }else{
            for(int j = 0; j != order.getItems().size(); j++){
                dishItems.add(order.getItems().get(j));
            }
        }

        saved = false;

    }
}

Today I learned about the use of a Singleton for global access to data, and I am wondering would it be a good idea to switch to this style of data access? It seems easier to control and a lot tidier with respects to the code.

I'd be interested to see what your opinions on this are. This link here is the pattern I would like to implement:

http://www.devahead.com/blog/2011/06/extending-the-android-application-class-and-dealing-with-singleton/

I should mention, the project is part of my studies in my course. I have to submit my code in a few weeks time, so I am looking for the best way to make it more efficient. So please let me know if you see anything that looks wrong as well!

Was it helpful?

Solution

There is very little reason to use Parcelable to move an object around inside a single Linux process. I suggest making your menu a static member of a custom Application object, something like this:

public class MyApplication extends Application {
    private static final List<MenuItem> menu;
    static {
        List<MenuItem> l = new ArrayList<MenuItems>();
        l.add(new MenuItem(...));
        ...
        menu = Collections.unmodifiableList(l);
    }

    ...

    public List<MenuItems> getMenu() { return menu; }

    ....

}

Make sure that the list is immutable, so that you don't have to worry about concurrency issues.

In your manifest:

<application
    android:name=".MyApplication"

... and access it with:

List<MenuItem> menu = ((MyApplication) getApplication()).getMenu();
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top