I have an application where i store info data in a sharedPreference
I want to create a static class which will hold the data from the sharedPreference (get and set) so i will not have to call each time to the sharedPreference(performance issues)
The static helper class dont have reference to the sharedPreference, is there any way to get hold of it without passing the calling activity as parameter?
Maybe getParent() ? or getContext() ?
I think you have 2 ways to do it :
You can pass a Context in the parameters of all your static methods. Then just use context.getSharedPreferences().
Create a static init method where you record the data of your SharedPreferences in static fields of your class.
For my perspective I prefer n°1 because in n°2 you have to call initand modify it each time you add a new data in the SharedPreferences
Consider implementing a Singleton class for this purpose. I am not sure if sharedpreference has a performance issue.
With a singleton class, you could store objects compared to shared preferences (strings).
Another way is to write your own MyApplication extends Application, where you can store whatever you want in scope of entire application and define whatever "static" methods you want. You could access to it via (MyApplication)yourActivityInstance.getApplication().
You will somehow have to pass a Context to your static class, preferably an application context. I suggest you override the onCreate() method of the Application class (you would need to subclass it) and set the context reference in your static class to getApplicationContext() from there. This way you can access the shared preference accessors from any other application component (Activity, Service, ...) without supplying the Context every time.
This is a bit late but here is an easy way i created.
Instead of creating your own SharedPreferences Helper class every time for every project you can use this open source library i created and make life simpler.
Android-SharedPreferences-Helper
Add this dependency and get started:
dependencies {
...
...
compile(group: 'com.viralypatel.sharedpreferenceshelper', name: 'library', version: '1.1.0', ext: 'aar')
}
Usage
Check the repository page for details about using advanced features.
Related
Currently, I have a database manager class that handles all operations to the database like this:
class DatabaseManager(val context: Context) {
private val db = Firebase.firestore
//Other functions, etc.
}
It makes use of the context passed in by different activities to perform functions to the database. The thing is, every single activity that requires database functions have to instantiate this manager class first, then call the functions. I would like to make use of the Singelton design pattern to make it such that all the activities will only use a single instance of the class. I believe kotlin's objects can do this, however I also need to be able to pass in the context of the activities into this manager class. Any assistance is appreciated, thank you!
I would recommend not doing that. The problem with Singletons is that they make code hard to test, you can't fake out the database. And for a database this is a particularly bad problem, as setting up all the right fake data can be painful. Instead, take a look at injection. It can do the same thing (make a single instance shared between everyone who needs it), but it manages that global state rather than having the classes themselves manage it via a static reference, passing it in (generally via the constructor) to whoever needs it. This makes it easy to provide an alternative or mock database when needed for testing. Injection used to be a bit painful to set up, but Hilt makes it a lot easier these days.
I am building an application in Android with multiple activities. I have a list of an object of type TodoItem that I get from a collection in Firestore database, and I need to access the list from more than one activity to make changes and updates to the list.
To do that, I thought about saving the list in the Application scope (is it a good idea?). For this reason, I created a class MyApplication extends Application (and added it to the Manifest file).
Instead of just adding the list as a class field of MyApplication I thought that maybe I should create a class named DataManager that will hold application-wide information such as my list of TodoItems (and here I ask again: is it a good idea? or maybe there is a better solution?).
At this point I am trying to decide what is a better approach to create and save the DataManager class:
One idea is to make DataManager a Singleton class and save it as a class field of MyApplication. This way, the activities will be able to get the instance of the class using DataManager.getInstance() without the need to get it from the application class with a getter method. In this approach, I will have to create the instance of DataManager and init the field of the application with it in the OnCreate() method of the application.
The second idea is to make it a non-singleton, add DataManager field to MyApplication, and create a getter named getDataManager() in the application class. The getter will check if the field is null (i.e. already initialized or not) and will create a new instance correspondingly. This way, the activities will get the instance using ((MyApplication) getApplication()).getDataManager().
I would like to hear what do you think about my approaches to solve the problem, and if you have any other suggestions or other ways to improve my suggested design.
A nice way when your data source is simple. You can create a singleton class to hold and manage data, including read and write from the singleton.
When you want to use complex data, you can store it to your device disk rather than memory. Android application support you to store your data with file, database, or key-value preference. As for your case, you can use database to store your todolist. Android support sqlite for these work, and we have official orm library called room.
raw sqlite: https://developer.android.com/training/data-storage/sqlite
room library: https://developer.android.com/topic/libraries/architecture/room
I have read some articles about how to use/extend the Android Application class but I am still kind of unsure if I can use it for my needs.
In my Application, on startup, i read a JSON configuration file. This configuration file contains some basic infos about an external device. Because I need this infos in several other fragments/activities I simply store an object representation of this json file as a member variable of my Application class.
public App extends Application {
private ConfigurationContainer configuration;
...
getters / setters
}
When I need it i call getApplication().getConfigurationContainer().
Is this OK for my needs?
Yes, It is ok.
Follow this steps.
1.Override onCreate() method and load all the json configuration in this method.
public App extends Application {
private ConfigurationContainer configuration;
public void onCreate(){
super.onCreate();
// load json configuration.
}
// getter setter
}
Declare this class in manifest file.
<application android:name="com.packageName.App">.
Use this configuration in all your activity.
App ap = (App)getApplication();
ConfigurationContainer conf = ap.getConfigurationContainer()
Yes it is reasonable to store globally scoped variables (or objects) in your Application class. You should be careful that you are not storing too much data here, as it will consume memory that is never recovered as long as your app is running.
Your concept is fine, but there are some nuances about using the Application class in this way, it is suggested that you create a Singleton class (instantiated by your Application) to store values like this.
Here is a great SO related to this: Android Application as Singleton
I want to hold all my variables somewhere where every Activity can access them and modify them. I tried storing my variables in xml file but it only works one way, I can access them but not modify them. The other option that I have thought about is creating seperate helper class that holds all my variables and offers getValue(); and setValue(); methods, but problem with this is that I think it will be resetted every time I make object of this class. So Is there any other way to have storage for variables?
Your senod option is nearer.
In your Helper class just add a static variable
See:
Class MyHelper {
..
..
public static int globIntVar;
Where you want to use :
MyHelper.globIntVar = 2; // Setter
public int var = MyHelper.globIntVar; // Getter
You can use android.app.Application for Sharing data between diffrence components of Appliction. see this post:
Android: How to declare global variables?
Your requirement is to create some Global Variables, you can create some Global Variable by Using Application Class.
Check Example:
How to declare global variables in Android?
Make one class in your application which store all variables which are used through out application ex.
public Class Const{
Public static int siteurl="http://www.xyz.com/";
}
Now where ever you want to use that variable write
Const.siteurl
I need to use getString() from most of the modules in my application.
But for some strange reason, it is tied to Application or Context, so that means I need to pass to each and every class in my application, the Application reference as a parameter.
This clearly violates one of the most basic principles of object oriented design.
Is there a way around this?
The 'strange reason' is that since the string resources are tied to your application, there is no way to access them without some sort of handle to it (the Context). If most of your classes that are not activities need to access string resources, you might want to rethink your design a bit. A simple way to not depend on a Context is to load the strings and pass them to your classes in the constructor.
Yes, there is a workaround - if you happen to (or can) pass a View (any View-derived class) to the constructor, and you assign it to a data member, then you can access the string resources from anywhere in your class:
String str_via_res = yourView.getContext().getString(R.string.str_via_res);
Otherwise, you will have to pass a Context to every class that needs access to these string resources.
you can extend android.app.Application class to create a static method to pass on the context across all classes in your application.
Refer : PhoneApp.java