unagi2x7
unagi2x7

Reputation: 39

How do I save an arraylist of custom objects so that when my android app is closed/restarted the arraylist stays the same

I have an arraylist of "Swimmer" objects and I don't want it to delete every time the app closes. I have read about serialization and using shared preferences, but I have no idea where to write that code or what it does.

The arraylist is currently stored as a public variable in the main activity class where it is accessed by the other activites.

public ArrayList<Swimmer> allSwimmers = new ArrayList<Swimmer>();

This is the activity where I use a list view to display all of the swimmers in the list and when one of the swimmers is clicked it goes to a new activity to display the swimmers info.

Everything is fine I just would like to save "MyActivity.allSwimmers" (the arraylist) somewhere where when the app closes and restarts its not blank

public class AllSwimmers extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.all_swimmers);

        ListAdapter theAdapter = new ArrayAdapter<Swimmer>(this, android.R.layout.simple_list_item_1,
            MyActivity.allSwimmers);

        ListView theListView = (ListView) findViewById(R.id.allSwimmersList);

        theListView.setAdapter(theAdapter);

        theListView.setOnItemClickListener(new AdapterView.OnItemClickListener()
        {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id)
            {
                Intent goToIndiv = new Intent(AllSwimmers.this, IndivSwimmer.class);

                final int result = 1;

                goToIndiv.putExtra("position", position);

                startActivityForResult(goToIndiv, result);
            }
        });
    }
}

Upvotes: 2

Views: 1939

Answers (2)

SuppressWarnings
SuppressWarnings

Reputation: 4182

Normally what you would want to do in order to be able to store custom data objects into memory, is to make them serializable.

You have to remember that persistent data outside the scope of a running application needs to be mapped into physical memory. In other words:

(As for) Serializing your data structure / object, means decomposing it into a format which can be stored. Of course the other aspect of serialization is the ability to pick up this serialized data from memory into your enviroment as volatile objects / structure again.

In Java this is all done by adhering your custom data to Serializable interface. However since we are discussing for Android, it is much more recomended to adhere to Parcelable interface (better speed, efficiency and security managing data)

So, at first, there really seems to be no other reasonable way of acomplishing what you're asking than by the serialization (using Parcelable interface) of Swimmer in one way or another...

Here is a simple example of data modelling POJO with Parcelable:

public class Profile implements Parcelable {

        private String id;
        private String name;
        private String category;


        public Profile(String id, String name, String category){
            this.id = id;
            this.name = name;
            this.category = category;
       }

       public Profile(Parcel in){
           String[] data = new String[3];

           in.readStringArray(data);
           this.id = data[0];
           this.name = data[1];
           this.category = data[2];
       }

       @Оverride
       public int describeContents(){
           return 0;
       }

       @Override
       public void writeToParcel(Parcel dest, int flags) {
           dest.writeStringArray(new String[] {this.id,this.name,this.category});
       }
       public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
           public Profile createFromParcel(Parcel in) {
               return new Profile(in); 
           }

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

The "problem" is that if you want to make use of SharedPreferences, it doesn't feature built in support for Parcelable, nor any other form of Serialized data mapping protocol since it is meant only for primitive key/value mapping by design. (SharedPreferences was built as means to store app configuration values that need persistance such as sound on/off, credentials, etc.., and not large data heaps).

However there is a rather neat "workaround" into using SharedPreferences out of convenience for storing custom Data objects with JSON. Of course the big advantage being JSON data easily serialized into String primitive.

Using default JSON api (org.json) you can make your own parse/convert functions valid for any type of POJO data. There is many different api for JSON data management and endless ways of manipulating it easily. Here is a basic example with nested json arrays:

SharedPreferences prefs = this.getSharedPreferences("MyCustomDataPreferences", Context.MODE_PRIVATE);

/* Assuming this JSON from SharedPreferences: "{animals : [{familyKey:Dogs},
  {familyKey:Cats}, {familyKey:Lizards}]}" */

//Notice how JSONObject just takes a String as an argument:

JSONObject obj = new JSONObject(prefs.getString("animalsJSON", null));

List<String> list = new ArrayList<String>();
JSONArray array = obj.getJSONArray("animals");

//Store into list all values with key "familyKey":

for(int i = 0 ; i < array.length() ; i++){
    list.add(array.getJSONObject(i).getString("familyKey"));
}

As you can see, this way you can simply store string values composed as JSON objects, then restore them back into java objects for use, using built in SharedPreferences.

Upvotes: 2

user2300851
user2300851

Reputation: 127

To do this, you would have to save the data in a SQLiteDatabase. Here is a great tutorial on how to do it:

http://www.androidhive.info/2011/11/android-sqlite-database-tutorial/

Upvotes: 2

Related Questions