Android detect when app is going to be updated - android

I am developing an android app and I need to save data when user is making a market update. Actually before the update is started. I tried using onDestroy() but that is not called when the app is updated. Do you have any ideas?
The problem is the app is saving data on a regular basis. And sometimes it happens that when you go and select update it tries to save on a file at the same exact time causing the data to get corrupted ... That's why I am trying to detect the update event.
File is saved at a fixed interval using a scheduled thread (e.g. 60 seconds). Also in the file I save a serialized Object using the classic writeObject(). This is happening only at a fixed rate of 60 seconds and also on the activity's onPause or service's onDestroy().
However if the fixed rate save happens exactly when updating (which causes the app to be destroyed) then the save is incomplete and the object get corrupted causing the next time the app is started to get an invalid object from the save file.

A general approach to save your data (from the Android developpers documentation) on android is to either use:
a key-value pairs on the shared preferences
saving the data on a files
or using a SQLite dabtase
You should use those even during the regular activity lifecycle and I dont see why they would not solve your persistence needs between updates as well.
In order to avoid corruption, use SQLite Transaction if you are using SQL and check this question for corruption safe strategies when dealing with files.

AFAIK there's no way to know when your app is going to be updated (you don't receive the package-related intents, because your app is not installed anymore during the update). It will simply be stopped as usual, all broadcast receivers unregistered, and updated.
What you can do, however, is add checks in your app so that when it starts it checks whether it was just updated and do whatever it is you have to do if it was. This is really simple, just store the current version of the app (which you can get via the PackageManager) in a shared preference, for example, and check the stored version against the current version every time the app starts.

Related

Preventing data corruption when app exits unexpectedly

I am currently developing an RPG game for Android devices and have just implemented a custom method of serialisation I use for saving the player's progress. The saving process can take up to half a second which is enough time for a crash to occur (either caused by the device (i.e. low battery power off), the user (killing the app) or a poorly written firmware/ROM (kernel panics) etc).
While saving the player's data, the old player data is overwritten. This means if a crash was to occur, and if the saving process were to be cancelled/interrupted as a result, the player's data would be lost. This is obviously not ideal and in the future, the game will be saving a lot more data and the save time will be much longer. This will increase the chance of a crash occurring during the save process.
I cannot reduce the save time as I am writing the minimal data the game requires to be able to resume after the app has been restarted.
What foolproof measures, if any, can I take to prevent such data corruption/loss from happening?
You can save your data in a temporary set of files and moving/renaming them when the process is complete, then deleting the previous save files.
If you're not confident with the renaming process, you can add these constraints :
ensure that data is consistent with a checksum
always try to resume from the last consistent saved state, depending on a rule of your own (name of the file, ...)
Another idea would be to cut into pieces your data in order to isolate state that do not change.
If save time is really long, you can try to use remaining CPU time during the game to pre-save parts of the current state that won't probably change (using a lower priority Thread, for instance).
You can save data to a SQLiteDatabase. If changes to the save data fails or is interrupted, the database will automatically be rolled back to a previous known state.
For additional security if you need to perform multiple updates atomically, put all your changes into a transaction. If any of the changes fail, the entire transaction will be rolled back to the pre-transaction state.
For more information about using SQLite, see documentation here. For easier manipulation of your save data in the event you want to share it with other apps or sync it to a backup server, consider interacting with your data via a ContentProvider.

Android Wear DataLayer API usage for synchronizing when phone app is closed

So, I want to learn this synchronization strategy instead of just using the simpler MessageAPI, but am really struggling with how to successfully implement this.
My project is like this: I make queries to download a small amount of text from an API, via my phone. I will make these queries every so often, haven't really decided on how often just yet. The data will update the watch, which should hold onto the last data received. After that first download occurs, I send data using a DataMap, to the Android Watch. I only send that once, because I believe that sets up a channel to continually send updates when ready. If that is wrong, please correct me.
My main question is this: what if the Android phone's app closes? Then the data object goes to null, and gets sent to the Watch as null? Or, should I send an object from a long-running service or shared preferences on the Android phone, so that the object is never null?
Think of the Data Layer as more of an event system, i.e., you update your data and you're notified on the other side when the data is updated (created, changed, or deleted). You don't have to worry about if the Activity is killed after that. Even if the data was 'deleted', you would be notified it was deleted.
On the Wear device, you would listen for the changes via a Service or Activity and update UI, DB, etc. accordingly.
It probably make sense to read through this Android training guide. (It isn't too long.) The Handling Data Layer Events section is probably the most useful.

How does android do GC?

Now I'm facing some problem in Android when memory is low or the application is killed by system.
Scenario 1:
I set some static members in a class, I found in some situation , it will be deleted by system when the application is still running.
My problem to this is : when does this kind of GC run?
Scenario 2:
If I switch to another large application and then switch back to my application ( named App_A). App_A sometimes will be recycled by system and restart the last activity when it be switched back.
But there are some application-wide data (like login info) I saved in a singleton.
My problem to this is : Dose the application-wide data saved in singleton will be deleted?
If so, is there a appropriate way to restore the data?
My effort is:
To Scenario 1, I will avoid to use static member directly.
To Scenario 2, I will save those data into file , after it be deleted, I pass Context to each public function to let each of them have the ability to restore the data. But I think it will be unfriendly when the function is used in some situation which need run quickly.
I can only answer about Scenario 2.
Android will try to keep recently used apps in memory, but if the user switches to another app and memory starts running low, the OS has the option to kill the recently used app to make more memory available to running applications.
I had the same problem, where I had some user-context data like username in a static singleton. This data would disappear when returning to the app after using a number of other apps.
The way I solved this problem was to use the activity's intent. Since the user data was retrieved at the beginning of the app, I would simply pass this data to subsequent activities in their intents. Because the OS stores the intent and uses it to recreate an activity not in memory, my data was no longer vulnerable to being garbage-collected.
Also consider other means of persisting data: Shared Preferences, file system, SQLite database. But never count on static data from previous execution being available at the start of an activity.
It is generally bad idea to use singleton to save some data.
Best practice is using any persistent storage - SQLite, Realm,JSON, or any file.
Easiest way is saving your login data for ex. in JSON - then in Application class parse it in onCreate method into POJO - then you can get it from any place of your app. And store to file when app is closing or on any change.
Anyway I suggest you to read Android guides about persistence, memory management and performance tips.

Stop an app from updating itself whilst being used

So I have discovered that an app can be updated whilst the app is in mid-use. My app records a workout and stores values into a local DB before uploading the workout.
During the last update, we altered the databases, adding new tables and columns. A certain number of users had their app update mid-workout, corrupting the database. While that can be fixed after the fact, it doesn't change the fact that the user has lost that workout. I've been searching but haven't yet found something that would allow for the app to wait on the update until it isn't in use.
Any suggestions are welcome.
Thank you for your time.
You can't stop the update, but you can make sure, there is no corruption, and there is no data lost: Before Update, the application's onPause() callback will be called - time to make sure, the App is in a recoverable state. This might include storing the momentary working set to some temp storage. After update, the app will receive onResume(), where you can load the working set back.

ANDROID - class Application

I'm trying to understand how the Application class.
I've noticed that need to declare it in <application> manifest within the tag and then can access the variables in other classes as they were global variables. And even out of the application the value of these varieties do not change.
However, if you unplug the phone, the next time you turn it on and start applying the value of the variables returned to its initial state.
I wonder if you can maintain the state of variables when we turned off the phone and reconnect it?
Application data is available as long as your application is "active". When the OS decides to terminate it to clear memory, so goes your application data (you typically don't control when this happens, as per the mobile development good practices: the OS decides on its own), and it's not persisted for the next time you start the app. So anything you store in the Application should be stored again each time the app is started.
It should be used to keep short-term data available to you. A good use case is when you need to access a complex data structure from multiple activities: it's not possible to use bundles for that. You can generate your complex data structure in your start activity, store it in the application, and then retrieve it in any other application that may need it.
But you should not use it for long-term persistent data. For that, the best is to use a SQLite database.
I'm not sure I fully understand what you mean, but it seems like you want to use Shared Preferences.
try this Question: Android - How Do I Set A Preference In Code

Categories

Resources