I am working with an android app and am looking for a way to establish some global preferences that will be later accessible to all all activities/classes in my app. This is similar to what i know some people end up using the AppDelegate in objective c programming. The answers i have seen on the net suggest that i either extend from Application or save the data to SharedPreferences. I would like to know if there is a way to combine the two approches so that in my app, i can keep calling properties of a Preferences object (such as Preferences.getName()) and also persist the data to SharedPreferences so that, in case Android decides to restart my application and i loose all the data in my Preferences object, i can still get it back from SharedPreferences and repopulate the Preferences object. Can anyone please let me know how this can be done and if it is viable?
See my answer at https://stackoverflow.com/a/13673178/338479
In short, I create a "singleton" class to hold my preferences, and the data persists as long as the application stays in memory. If the application is killed by the system, the singleton class silently reloads it later.
It's also possible to do this by extending Application class, but conventional wisdom holds that there's no real advantage to doing it this way.
Related
I am building my first Android app. I need to add a specific set of headers to each web api call and want them to persist even when the app closes. I implemented them in shared preferences but now I need to drag around a context for every call, which seems like a bad way to do things. I would like to set the values on initialization of the app. Have them usable by the WebAPIHelper object without much trouble, and when the values change, save them. I am using Room so I could save them there.
Is it standard practice to use LiveData or extend the application object to have access to the values for use within an object such as my WebAPIHelper, or is there another, better way? Is it best to persist these values in a database or SharedPreferences?
UPDATE
I have seen some examples of extending the application object like here and here. I would want to get the values from sharedpreferences onCreate and save them to sharedpreferences by calling a setXXX, but I haven't gotten that to work.
Also I was concerned about this statement I found in an article:
"Storing data in the Application object is error-prone and can crash your app. Prefer storing your global data on disk if it is really needed later or explicitly pass to your activity in the intent’s extras."
The implication of this would mean that I would need to pass the header values to the WebAPIHelper object all the time. I am passing the context object everywhere now so I guess it's 6 of one vs 1/2 dozen of the other.
The other way to do this might be to extend the AndroidViewModel class in a BaseViewModel, add the properties there from SharedPreferences so they are available through all ViewModels in the app. Has anybody done it this way?
Should I use a singleton class or preferences to store the data that is shared in the program. For example, say the user can enable or disable location tracking. The state of tracking has to be stored and shared with the SERVICE that handles the location changes. In such case, should I use a singleton class or preferences to persist the choice for a background SERVICE ? Please also relevant supporting points to your choice.
The purpose of SharedPreference is exactly store preference settings and status values.
Singleton restricts the instantiation of a class to one object, that is a different matter.
If you want to avoid the lost of data when the application is closed, if you don't use Preferences you have to create manually a method to store and load your data on a file, so SharedPreference is the best choice, if you want to share an object only during the program execution you can use singleton to restrict its instantiation, however if the value to store is a String or a primitive using Preference also in this case has no side effects but is a bit dirty programming choice.
Singleton - Saves Data in variables and get deleted when Application is Destroyed.
Shared Prefs - Save Data outside of your Application so u can later use even application is destoryed.
SharedPreferences, Service, and Singletons are substantially different. None of them can be used INSTEAD of the other one. If at ANY situation you though you can use one instead of the other, you can be sure you did not understand their application very well.
As one example difference, SharePrefs are saved in the disc so they are persistent, while Singletons are not.
I am new to android development and I see that there are different components (activities, services, etc.) where each component has a different life cycle.
I am encountering a situation where I have an object that should be accessed by different components. Namely, I have a list of objects that changes dynamically, and that list should be accessed by:
An activity that displays the list in a ListView
A broadcast receiver, that responds to alarm events scheduled in the AlarmManager.
The broadcast receiver may kick in hours after the activity was used. At this time, the activity may or may not be still alive in memory.
Is there anywhere I can put the list so it will be accessible to all app parts? My idea was to serialize the objects I need to share, write them to shared preferences and then recreate them whenever needed. I'm not sure it's a good idea, and even if it is - how would I design it? when would writing to shared preferences (or somewhere else) occur? when would reading occur (it would be preferable to read the object from memory when possible)?
You can put it in SharedPreferences if it a compatible data type, or serialize the list to a file in the internal or external storage (see saving files, you probably want internal storage for your situation).
You can read the list in the onResume() method of the Activity or the onReceive() method of the receiver. Writing will occur whenever a new element needs to be added to the list, you will deserialize the list, add the element and re-serialize it. You may need to place the reading and writing in a synchronized block or method to prevent simultaneous access.
If the list may be added to outside of the Activity when the Activity is resumed you may need to provide a broadcast receiver or other mechanism for the Activity to be alterted and reload the list.
As Gabe pointed out, you could store it in a static variable somewhere, but the way you described the situation serializing sounds like a better option. Otherwise the list is gone if your process is terminated by the Android system.
As kcoppock pointed out, you could use an SQLite database to store the data, but this sounds like overkill from what you described. You will be in for some additional coding without much benefit.
What you are looking for is the Android Shared Preferences. You can access Sharepreferences using getApplicationContext() from an Activity or a Service.
Hope this helps
If you don't want it permanently stored, put it in a static variable somewhere (anywhere they both agree to- a separate class would be a good idea). Then you can access the list unless Android kicks the class out of memory- which it should only do it its terminating the app due to lack of memory, in which case it doesn't matter much anyway.
If you do want it permanently stored, the filesystem is the best way. You'll need to synchronize access to it of course.
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
Ddms tells that, when I recall my class called in the past, it performs an onCreate() instead of onResume() that I expected...
I noticed that values that I stored in variables of my class in this case are lost and are null.
I presume that Android decide to do so to free memory resources (isn't it?).
I know that I could use Sharedpreferences to store data in a persistent way and then retrieve... But this is a really dirty way, in my opinion.
So, my question: how to have variables' values preserved also after an onDestroy() (I think?) that Android decided automatically?
Android will terminate your process at any time when you have no visible activities. For example, the user might go into Settings and terminate your app.
Static data members (my interpretation of your "variables of my class" description) are only meant to be caches, at best. They are no substitute for a persistent data model, whether you use a database, an XML file, a JSON file, or whatever.
So, if you want "variables' values preserved", save them someplace persistent.
You might find this page on data storage helpful. If your data is primitive, SharedPreferences are the recommended route. (Why do you think they are dirty?) If you need to store an object, you can use internal storage, as documented on that page.
http://developer.android.com/reference/android/app/Activity.html#onSaveInstanceState(android.os.Bundle)
If you don't like SharedPreferences, then you might want to look into Content Providers Even though Content Providers share data across applications, they also provide functionality for you to store persistent data in SQLlite and files that are available only to your app. In this case data stored in this fashion will be available even after closing and restarting your app.
You can save dynamic state by passing name:value pairs or serializable objects using the Android Architecture and the methods onSaveInstanceState and onRetainNonConfigurationState. You can persist state as explained in the other answers by writing to prefs and doing database writes.
I've been using custom Application class to store data over application life line.
How to declare global variables in Android?