I am trying to read data from the SQLiteDatabase when my application opens, and commit it all by inserting all of the changes when the Application closes. I know this isn't the most efficient, but the assignment I am working on is about UI mostly, not how the back-end works. How can I go about doing this? I tried creating my own Service class, but then I soon discovered that I can't seem to use the constructor for the Service. My goal is to use some kind of onCreate() and onDestroy() functions to work with the database when the App is started/ended.
In the situation like yours, the best approach is to use onPause() as described here:
Note: Because onSaveInstanceState() is not guaranteed to be called, you should use it only to record the transient state of the activity (the state of the UI)—you should never use it to store persistent data. Instead, you should use onPause() to store persistent data (such as data that should be saved to a database) when the user leaves the activity
Related
I was wondering in which Android lifecycle function (e.g. onPause, onDestroy) should sqlite database calls be initiated within.
Currently I have a model object that is being manipulated by the user within an activity, and is saved to disk when the app shuts down.
I thought about using onSaveInstanceState, but I realize that its not called during app shutdown (as it doesn't make sense to save state in this scenario)
The documentation says:
You should … use onStop() to perform relatively CPU-intensive shutdown operations. For example, if you can't find a more opportune time to save information to a database, you might do so during onStop(). […]
I currently store my app data for an Activity in a Parcelable object. On orientation change, I save it and load it by using onSaveInstanceState and onRestoreInstanceState.
I want to save the data to the database when the user exits the activity.
And, I want to minimize the database calls. So,
Where should I write the code to save the data to database? Is it onPause(), onResume(), onStop() or onDestroy()?
If you're really talking about best practices, then none of the above.
An Activity is View-tier object. Some might argue that it is a hybrid Controller and View. In either case, it's not a Model or Business-tier object.
If your data is important enough to write to a database, then I'm guessing that it's not view state, it's probably domain data. So, the best practice would be to let the Model/Business tier (which is completely decoupled from the Activity) handle it. And given the nature of mobile apps, I'd write to the database (asynchronously, of course) whenever the data changes, without regards to the lifecycle of the various Android components.
I currently store my app data for an Activity in a Parcelable object
Since the rest of your question is about database I/O, please note that Parcelable has nothing to do with database I/O.
I want to save the data to the database when the user exits the activity.
I would recommend that you save the data when the data changes, rather than wait and risk losing that data (e.g., app crashes).
Is it onPause(), onResume(), onStop() or onDestroy()?
It is not onResume(). That lifecycle method is called as part of activity coming onto the screen, not when the activity is leaving.
It is not onDestroy(), as there is no guarantee that onDestroy() will be called.
Either of the other two are reasonable. The primary difference is visibility:
If an activity takes over the foreground, but that activity is themed like a dialog or otherwise allows your activity to peek through, you are only paused
If an activity takes over the foreground, and your activity is no longer visible, you are paused and then stopped
A correction to the accepted answer: (I am surprised it is Mark Murphy!)
From the android documentation on activity lifecycle:
onPause() execution is very brief and does not necessarily afford
enough time to perform save operations. For this reason,
you should not use onPause() to save application or user
data, make network calls, or execute database transactions;
I want to save some small data structures (~1kB total), as well as the user's preferences, while my app is closed. The settings are modified only in my PreferenceActivity, but the data structures are modified in pretty much every activity. I've extended Application and made all the data structures and preferences static. I've then tried saving to SharedPreferences in my application class's onTerminate() and loading it again in onCreate(). However, onTerminate()'s documentation states that "It will never be called on a production Android device, where processes are removed by simply killing them".
Answers to this question suggest saving to SharedPreferences in the onStop() method of each activity modifying their data. Will this guarantee that the data is saved in all cases? Is there a way to avoid the waste of saving every time the user transitions between activities (or should I even care)?
I would honestly just save in the onPause() of each activity as is recommended by Android (i.e. when you write an email notice how the draft is saved when the app pauses, such as if the screen turns off). Unless you notice that it is causing lags/delays, it probably won't matter too much.
If you do notice lags with this "autosave" method, then you should probably have some sort of "Save" functionality implemented in each activity, which could, for example, entail using a ProgressDialog / AsyncTask combination.
I was watching one of Google's app reviews and they were ripping into this guys' app who had a save button and if you didn't save before leaving it would pop up a dialog. They said an android app should just save and not bother the user.
I have a fragment and have several fields and need to determine when to save the data into a SQLite database. I was thinking of saving on exit of each field via the onFocusChange event? Or maybe that's too often? Perhaps the fragment's onPause event? When should I save (specific event please)?
Fragments are much like the activities when it comes to lifecycle. So onPause() is the right place to save persistent state, later after onPause() it may be too late and can lead to data loss. Google recommends to use "edit in place" user model. That is, save edits immediately, in your case saving data when the user switches between input fields is good approach. This prevents data loss if your Fragment/Activity is killed by the system. If you think it can take few seconds to save your state you can use also IntentService in onPause(). In your scenario I would execute AsyncTask updating your database when the user switches between input fields, maybe with detecting if change really occured.
Edit: If you are using ContentProvider than consider using AsyncQueryHandler instead of AsyncTask.
public void onDestroy()
Called when the fragment is no longer in use. This is called after onStop() and before onDetach().
I would probably use that; it would mean the user is done using that fragment. I don't know of any cons in doing it that way or your way.
When I want to save some state behavior of the activity, The docs says that we should implement OnSaveInstanceState and OnReceiveInstanceState.
They say that this will save the activity state even after destroy or restarts. I care more about destroy (the activity is completely gone) , does that mean the bundles are considered persistent ?
when I open a pdf reader, clost it and open it again i see that it opens in the same page I was in. is this implemented using Bundles or oth
To store persistent application data use Shared Preferences. Shared Preferences are simply sets of data values that are stored persistently. By persistence, we are talking about data that persists across application lifecycle events. In other words, the application (or device, for that matter) can be started and stopped without losing the data. The next time the user launches the application, that data will still be available.
Some Games use Shared preference for exemple to store the level of the game reached, the player's name ...
see this link to learn how to use Android Preference API
Preference are simular to bundles However they are persistant and bundle are not!!
Keep in mind that if you need to store persistent data you have 4 options to do this:
Using Shared Preferences
Using SQLite Databases
Using Internal Storage
Using External Storage
Bundles are not persistent, the documentation says not to count on it, onSaveInstanceState() is called when the activity is about to be killed by the system, but for a known restart (for
instance on a screen rotation.) If your activity is killed because the system needs more resources (while the
activity is in the background), onSaveInstanceState() will not be called, but onPause() will. onSaveInstanceState()
really is not meant to save persistent data, as the doc states.
You can sorta consider SavedInstanceState() permanent but it's not recommended to use it for saving application related data in a persistent manner as It's not guaranteed to be called and it's not recommended by the authors themselves.
so, Only use them for saving user interface state changes (background color, currently selected items ,..) and use other method for persistence like : SharedPreferences, Files and SQLite.
Bundles are not persistent, and the documentation for them specifies that using them for persistence is not a good idea as their internal format may change between devices or even OS versions.
SharedPreferences, on the other hand, can be persisted and are the recommended way to store information like current app state.
Some relevant parts from SavingActivityState
:
Note: There's no guarantee that onSaveInstanceState() will be called before your activity is destroyed, because there are cases in which it won't be necessary to save the state (such as when the user leaves your activity using the Back button, because the user is explicitly closing the activity).
There is no guarantee data will be stored, especially in the case where your user exits the app.
Note: Because onSaveInstanceState() is not guaranteed to be called, you should use it only to record the transient state of the activity (the state of the UI)—you should never use it to store persistent data. Instead, you should use onPause() to store persistent data (such as data that should be saved to a database) when the user leaves the activity.
So like K-ballo said, used SharedPreferences if you have persistent data to store. onSavedInstanceState() is mostly useful for storing UI related data.
As every one else has recommended use shared preference and you should do this saving in onDestroy and onSavedInstance both.
When android is going to run low on memory, its just going to kill your application and call your onSavedInstance without calling onDestroy etc. Save your context in bundle it passes in onSavedInstance. When your app comes in foreground again, android will take care of restoring your back stack of activities. But this time it will pass you the bundle in your onCreate for each activity which will have all the values you saved in your onSavedInstance while your app was getting killed.
Hope this helps.
Short answer: It's not permanent.
Long answer: From "Android Programming - The Big Nerd Ranch Guide":
When onSaveInstanceState(...) is called, the data is saved to the
Bundle object. That Bundle object is then stuffed into your activity’s
activity record by the OS
...
So when does the activity record get snuffed? When the user presses
the Back button, your activity really gets destroyed, once and for
all. At that point, your activity record is discarded. Activity
records are also typically discarded on reboot and may also be
discarded if they are not used for a long time.