Android - Idle condition data loss - android

Is there any way to avoid static data loss in Android if device is kept idle ?
I am having static object which will store some values from activity UI.
If device is kept idle for 4-5 hours that static object will be removed to use memory for other running applications.
If I am doing it wrong, is there any other way to avoid this ?

You can't avoid it. Android can kill your process at any time and does not guarantee to call you back.
This only happens if your app goes to the background. Save your data in onPause() and reload it in onResume(). See the Android documentation for Activity lifecycle for more information.

No, that's how Android is meant to work.
Simply, if data are meant to be persistent, ie if its lifecycle spans beyond the one of the Activity which created it, save it on a persistent storage (ie internal memory), in a flat file or in a database depending if the data has an inner structure or not.

Related

Android - Save instance state in Application instance (TransactionTooLargeException )

Android 7.0 start throwing TransactionTooLargeException while restoring instance state if the parcel size is over the limit.
But my application have to save the loaded content which has no size limit.
So it's very easy to cause this error.
Is it safe to save instance state in Application instance?
Will it be deleted while the Activity is in background?
Is there a way to save large data without throwing this exception?
To answers these questions one by one :
Is it safe to save instance state in Application instance?
Not if want to retrieve that data after your app's process has been killed by the OS and later restored. For that, you need to persist data to disk somehow. There are always two parts to properly handle saving state : handling configuration changes (like rotations) which do not involve process death and actual process death and restoration. Putting state in the Application instance (or any singleton) solves the first problem but not the second.
Will it be deleted while the Activity is in background?
Depends what you mean by "in the background". That can sometimes mean "the Activity exists but is in the stopped state". In that case, your data is fine. But your entire app process can be killed while the app is backgrounded and later restored when you return. In that case, your data will be gone if it is not properly saved to disk somewhere.
Is there a way to save large data without throwing this exception?
Yes, write it to a database and restore the data from there instead. Alternatively, you can use this library that automatically handles persisting / restoring your Bundles to / from disk for you : https://github.com/livefront/bridge .

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.

Persisting state in the android Application class

I am developing an Android application consisting of over 10 activities. I have some state objects that I access in almost every activity and for this purpose these were implemented as global static variables in the MyApplication class.
I noticed that this approach is OK as long as the user is "in" the application. However, when he presses the home button and opens another apps and then goes back to my app through the "Recent activities" button, I see that the Android system resets the statics from the MyApplication so I have to deal with NullPointerExceptions. I know that this behaviour is caused by Android killing and recreating the application process.
I know that the best way to persist this kind of data is using SharedPreferences or SQLite, and I have no problem checking if MyState==null in the onCreate for and restoring it, but the problem is that I don't know when to properly store my state object (in prefs or database). I tried to override MyApplication's finalize() - no good, I saw that onLowMemory may not be called, I don't see how can I use onPause, OnStop and so on because I have so many activities that the serialization de-serialization would considerably slow down the app.
Any thoughts?
Thanks in advance!
It is better to not depend on the Application class unless you need to load some data, before anything else is started. Android can kill your process at any time to free resources, so your app should be able to handle this. Save all of your data in a snigleton class, and load it lazily -- check for null, and if so load on first access. It the state needs to be persistent, consider staving it file/shared prefs. If not, your app can probably live without it, so just make sure you check for null, etc.
Generally, you should persist state when activities become inactive -- onStop(), onPause(), but you can save as soon as it makes sense (e.g., the user has entered all required data). Spin off an AsyncTask to save data in the background and let the user continue their work.

Data on a Extended Application class lost when app is closed

I´ve an Android Application that holds some static objects on an class that extends Application class, using the same approach as exemplified here.
The objects that is hold by this class is shared and manipulated between all activities on my app.
Everything works well, but, some time ago, I noticed that when the application runs on backgroud for some time, when it´s restored, the data that was stored on the extended class has gone, and the app starts to throws a lot of NullReference exceptions.
I think that this happens because of the application was being temporary destroyed by the OS, to be recreated when we need to use it again.
So, how could I handle this scenario? Is there any way to discover that the application is being temporary destroyed, without subscribing to the onDestroy event of an Activity? On a test that I did, the onDestroy event was not called when I asked the background process of my app to being stopped.
Thanks a lot!
There is no way to determine when the proccess will be killed, so you always should store important data somewhere(sd-card for example) and restore it in onCreate() method of your App class.
Also take a look at onLowMemory() and onTrimMemory(), release all unnecesary data in memory to help the OS prevent destroying your app, cause one of the reason to determinate your app is a lack of memory.
No, there's no way to tell when you need to persist data that you store in static variables like that. There's no callback that the systems notifies you about this, at least to my knowledge.
So you should only use static variables to store temporary data, or cache data accessed from peristent sources. I've faced this problem in many of my projects, and I always ended up using intents / shared prefs / sqlite / etc. to reliable store data across Activities.

Is ApplicationData safe place to store data during onPause?

In my application I'm storing all data in ApplicationData so that it can be easily shared between activities. My understanding is that this data should persist for the full life cycle of the application from the initial onCreate to the final onDestroy. That being the case, is there any need for me to store data in persistent storage during the onPause of all but the top activity?
My understanding is that this data should persist for the full life cycle of the application from the initial onCreate to the final onDestroy.
Not exactly. Your process and custom Application class will remain around as long as Android lets it. Android may terminate the process outright to free up memory in an emergency. Not to mention that battery-powered devices may have their batteries go dead.
That being the case, is there any need for me to store data in persistent storage during the onPause of all but the top activity?
Only if you don't want the data. Use Application (or static data members) as a cache only.

Categories

Resources