Monday, 25 June 2012

How to Send an extended ArrayList through an intent


In this article am going to look at how you can pass a custom list from one activity to another.  This being one of the things I had to deal with in my not complete android application, well, I thought it was worthwhile blogging about it.

Let’s first look at what my code supposedly looks like before we jump into what is happening. 

I have Customer class:

import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;


class Customer implements Parcelable {
       
        private int iProperty1;
        private String sProperty2;
       
        public Customer(){
              super();
        }
       
        public Customer(Parcel in){
              super();
              iProperty1 =in.readInt();
              sProperty2=in.readString();
        }
       
          public int Property1() {return iProperty1;}
          public void Property1(int value) {this.iProperty1 = value;}
         
          public String Property2() {return sProperty2;}
          public void Property2(String value) {this.sProperty2 = value;}
         
          @Override
          public void writeToParcel(Parcel dest, int flags) {
            dest.writeInt(iProperty1);
            dest.writeString(sProperty2);
                 
          } 
         
          @Override
          public int describeContents() {
          return 0;
          }
         
          public static final Parcelable.Creator<Customer> CREATOR= new Parcelable.Creator<Customer>() {
            public Customer createFromParcel(Parcel in) {
                  return new Customer(in);
            }

            public Customer[] newArray(int size) {
                  return new Customer[size];
            }
          };
         
         
  }


A customer List,

import android.content.Context;
import java.sql.Array;
import java.util.ArrayList;


class CustomerList extends ArrayList<Customer>{
       private Context context;
       private CustomerDataSource oDataSrc;

       
       public CustomerList(){
             super();
       }
       public CustomerList(Context context){
             super();
             this.context=context;
             oDataSrc = new CustomerDataSource(context);
       }
       
       public void Save(){
            try{
            for(int iItem=0; iItem<this.size(); iItem++ )
            {
                  Customer oCustomer=this.get(iItem);
                  if (oCustomer.IsDirty()){
                        oDataSrc.Save(oCustomer);
                  }
            }
            }
            catch(Exception e){
                  Log.e("ERROR", e.toString());
                  e.printStackTrace();
            }
       }
       public void Load(){
             try{
                  this.addAll(oDataSrc.GetCustomers());
             }
             catch(Exception e){
                        Log.e("ERROR", e.toString());
                        e.printStackTrace();
             }
       }

       public Boolean RemoveCustomer(Customer oCustomer){
             try{
                  oDataSrc.Delete(oCustomer);              
                  this.remove(oCustomer);
                  return true;
             }
             catch(Exception e){
                        Log.e("ERROR", e.toString());
                        e.printStackTrace();
                        return false;
             }
       }
}

Lets begin with the customer class, I know you have realized that it has implemented Parcelable interface. Parcelable is an extremely efficient, low level Protocol which serializes your objects into byte stream. Two methods have also been overridden for similar purpose;

  • writeParcelable(Parcelable, int) -

This method flattens the object data to the Parcel, allowing that object to be reconstructed from the appropriate class loader when later reading. Each element in the object should be parceled individually as I have done with the two class properties.

  • describeContents() -This defines the kind of object you are going to parcel.

To reconstruct the object I have defined a constructor, which will read data from the parcel and map it back to the object.
  public Customer(Parcel in){



I also have an class "class CustomerList" which extends an ArrayList. This basically loads all the customers data from the repository and saves back in. This ArrayList object will be used to sustain the customers data within different activities which was also a bit of  a pain. So how do I do this?



CustomerList oCustomerList = new CustomerList(this);

oCustomerList.load(); // Load all the customers

Intent intent  =  new Intent(this, CustomersActivity.class); //Declare an Intent
intent.putParcelableArrayListExtra("oCustomerList", oCustomerList); //send the Customer list to


startActivityForResult(intent, EditREQUEST_CODE); 


Reconstructing  the list, was tricky because after the object was flattened I could not directly parse it back to a type  CustomerList therefore I had to manuver.

Declare my custome arraylist to persist the original customer list ;

CustomerList oCustomerList = new CustomerList();

The declare another Arraylist since the intent will only return a type arrayList.

ArrayList<Customer> oArraylist = extras.getParcelableArrayList("oCustomerList");

//populate the customer list with the data from arraylist

oCustomerList.addAll(oArraylist);

//Clean up
oArraylist.clear;
oArraylist=null;


No comments:

Post a Comment

Comment