Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Best method for saving data - preferences, sqlite, serializable or other?

Tags:

file

android

I've been investigating alternative methods for saving my game's data between turns, and wonder if anyone can point me in the right direction.

I have approximately 32k of data which must be saved during onPause. I ruled out preferences due to the sheer quantity of data. I spent a few days playing around with SQLite but couldn't get the data to save in less than two seconds (although the time certainly hasn't been wasted).

I've decided that I'll use the database for loading constant data at the beginning of the game. This will certainly make it easier to tweak various parameters and default values in the game. But this still leaves me looking for the ideal method for writing data.

The data that needs to be saved is basically nine occurrences of class A and nine occurrences of class B. I'm an intensive month into the learning curve of Android (and the nuances of Java, coming from a C++ background) and have been googling like crazy. This brought two possibilities to mind -

1) Serialization (ObjectOutputStream)

I thought this would be the perfect solution but, having read several other posts regarding the subject, gather that it isn't highly recommended on the Android platform due to speed and memory allocations provoking the garbage collector into a potential rage.

2) DataOutputStream class

My current thought is to add Load and Save functions to both classes and to use DataOutputStream and DataInputStream calls in them to write and read the data respectively.

The data in the classes are primitives (strings and ints mostly) and arrays of primitives, so there's nothing too complicated in there to break down. Would this second solution seem a good, viable one? Or are there other solutions that I am unaware of as yet?

like image 872
Rok Avatar asked Feb 10 '11 20:02

Rok


3 Answers

You should use an Async task to save the data, I used this method to fetch highscores at the start a game:

new HighscoreTask().execute(this);

the Async task looks like this:

public class HighscoreTask extends AsyncTask<MainView, Void, Void> {

    protected void onPreExecute() {
    }

    protected void onPostExecute(final Void unused) {
    }
    @Override
    protected Void doInBackground(MainView... params) {
        HighScoreFactory.syncScores();
        return null;
    }
}

All the database interaction happens in HighScoreFactory.syncScores() this can take as long as it needs because it happens in the background. In my case it sends an HTTP request to an external server and loads these into a database. It's never caused any problems and works seamlessly.

like image 84
Kevin Avatar answered Sep 29 '22 12:09

Kevin


Why do you have a 2 second limit on your database write? If it is purely for the sake of UI responsiveness, then there is another approach you can take.

You don't actually have to perform the save within your onPause method itself, you could just kick off a new Thread that actually does the save for you.

private void backgroundSave(){
    Thread backgroundThread = new Thread() {
        @Override
        public void run() {
            //do save here
        }
    };
    backgroundThread.start();
}

@Override
protected void onPause() {
    super.onPause();
    backgroundSave();
}

You could alternatively use an AsyncTask for this.

You might have to consider the case when a user attempts to restart your app before the save is complete, but that shouldn't be too hard to take into account.

like image 23
dave.c Avatar answered Sep 29 '22 12:09

dave.c


Have you tried insert data to the database in transaction?

try{
 db.beginTransaction();

 //here insert data to database    

 db.setTransactionSuccessful();
} finally {
 db.endTranscation();
}

That can speed up operation.

like image 22
pawelzieba Avatar answered Sep 29 '22 11:09

pawelzieba