Access common functions static? - java

I have a question which might be more general, but I came across it during android dev:
How can I best share own common used methods?
Eg retrieving a shared preference by key is always the same code. But if I have to use it in different Fragments or Activities, I always have to copy the same code:
private void setSharedPrefs(String key, String value) {
SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(context);
SharedPreferences.Editor editor = settings.edit();
editor.putString(key, value).commit();
}
It it a good habit to make this a public static in a GlobalUtils class or so?
How would you handle these kind of functions?

You could definitely make a static class such as GlobalUtils or even a dedicated class for SharedPreferences. You just have to pass in a Context to the method so that you could get the SharedPreferences object. You can take this as far as you need it to go; I've made these classes countless times. I even have a thread-safe SharedPreferences wrapper :-)
EDIT: Just looked at my code again and half of my SharedPreference wrappers are static and the rest are lazily instantiated. That being said I think you should do whichever you feel comfortable with as long as the rest of your code doesn't necessitate it going one way or the other.

Yes you could make it public static:
public static void setSharedPrefs(Context context, String key, String value) {
SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(context);
SharedPreferences.Editor editor = settings.edit();
editor.putString(key, value).commit();
}
Be careful in some situations where you may hold onto the context after an activity has died, that is bad.
A more likely scenario your describing could be to create a class like this:
public class MyPrefs {
SharedPreferences settings;
SharedPreferences.Editor editor;
public MyPrefs(Context context){
settings = PreferenceManager.getDefaultSharedPreferences(context);
editor = settings.edit();
}
public void saveName(String name){
editor.putString("name", name).commit();
}
}
You would lazy init this class in your class that extends Application and have a getter in there to retrieve it, with something like:
MyPrefs prefs = ((MyAppication) getContext().getApplicationContext()).getMyPrefs();
and use it like so:
prefs.saveName("blundell");
EDIT
Example of Lazy initialisation:
private MyPrefs prefs;
public MyPrefs getMyPrefs(){
if(prefs == null){
prefs = new MyPrefs(this);
}
return prefs;
}
N.B This is lazy initialization within a class that extends Application therefore this refers to your application context and will live for the duration of your Application. If you where using an Activity context you would not want to use lazy initialisation. (So use the application context!)

I usually write common code inside a static method in a different class. So that i can call the static method anywhere in the project without every time creating new class objects.

Related

Save string/EditText in memory android studio

I have a problem with save the value of string or editText in java android. When I redirect from FirstActivity to Second and return after it to First, I need that a String that i fill earlier stay in the place that I wrote it. (Like a cookies in js).
You could use shared preferences for this process.
In that case, Best practise to create SharedPreference and for global usage, you need to create a global class like below:
public class PreferenceHelper {
private final SharedPreferences mPrefs;
public PreferenceHelperDemo(Context context) {
mPrefs = getApplicationContext().getSharedPreferences("MyPref", 0); // 0 -for private mode
}
private String PREF_Key= "Key";
public String getKey() { // To retrieve data
String str = mPrefs.getString(PREF_Key, null);
return str;
}
public void setKey(String pREF_Key) { // To store and edit Data
Editor mEditor = mPrefs.edit();
mEditor.putString(PREF_Key, pREF_Key);
mEditor.commit();
}
public void clearData(string pREF_Key){ // To delete data
editor.remove(pREF_Key);
editor.commit();
}
}
Then you could use these functions with global class in your activity class to store, retrieve and delete the shared preference data.
Hope this will solve your problem!

Is this an efficient way to get/set multiple SharedPreferences in a singleton helper?

My Android app stores 15-20 settings pairs with SharedPreferences, and I've been using a helper class so I don't have to create a new method in every class that needs to retrieve them.
Some retrievals are starting to take >100ms, and I'm not sure my current method is efficient for performance since it passes in the Context and creates a new SharedPreferences object each time. This happens numerous times throughout the app's AsyncTasks.
Here's what I've been doing:
public class SharedPrefHelper {
static void setDefaults(String key, String value, Context context) {
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
SharedPreferences.Editor editor = preferences.edit();
editor.putString(key, value);
editor.apply();
}
static void setDefaultsInt(String key, int value, Context context) {
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
SharedPreferences.Editor editor = preferences.edit();
editor.putInt(key, value);
editor.apply();
}
//... continued with other variable types and getDefault variants
//.......
}
Would below be a more efficient way of handling this?
public class SharedPrefHelper {
private static SharedPreferences preferences;
static void init(#NonNull final App app) {
preferences = PreferenceManager.getDefaultSharedPreferences(app);
}
//App is the Application class, init is called in onCreate()
static void setDefaults(String key, String value) {
SharedPreferences.Editor editor = preferences.edit();
editor.putString(key, value);
editor.apply();
}
//... continued with other variable types and getDefault variants
//.......
}
Or are there other variable keywords that would do better (final, etc)?
+100ms is a long time for such a simple action and so little key-value pairs.
I think the problem is not here.
However, to answer your question, yes, the proposed alternative is certainly better than the original one. Indeed, there is no point in calling getDefaultSharedPreferences(context) multiple times, as that method points to a default file, which is set application-wide.
So just store it as instance/static field (but avoid static as much as possible).
preferences.edit()
returns a new, fresh, Editor (EditorImpl, it maintains a Map of the changed key-value pairs and then persist everything on apply) every call, so you're totally fine.

SharedPreferences, Singleton Class - What should you use for calling, editing, saving and recalling two integer values

My app will carry two scores the entire time, calling them, adding to them, saving them, and later calling them back again for other functions and editing. What is the best method for this? These will be the only numbers needed throughout the app.
All I am looking for is the most efficient option I should implement. And if possible a simple example of making, editing, saving and recalling. Thank you.
I suggest using SharePreferences because you are only need to store very small data.
Hint:
synchronized void saveScores(final Context contex, final String scoreOneKey, final String scoreTwoKey, final Integer scoreOne, final Integer scoreTwo){
final SharedPreferences sharedPreferences = context.getSharedPreferences("user.score.key", Context.MODE_PRIVATE | Context.MODE_MULTI_PROCESS)
final SharedPreferences.Editor preferencesEditor = sharedPreferences.edit();
preferencesEditor.putInt(scoreOneKey, scoreOne);
preferencesEditor.putInt(scoreTwoKey, scoreTwo);
preferencesEditor.commit();
}
Things to Note here are:
You are method must synchronized as multiple threads can access the game score.
Notice the sharedPreference access controls (MODE_PRIVATE | MODE_MUTI_PROCESS) that tells the OS that this sharedPreference is not accessible by other apps but at same time it is possible to access it from multiple process of your app ( if you can even encrypt the scores before saving them.)
UpdatedYou can use SharedPreferences To save Scores When you will call getFirstScore() first Time it will return 0 as the variable is not yet created and then you can call setFirstScore() to save it.
public class ScoreDatabase{
private Context context;
private SharedPreferences pref;
private SharedPreferences.Editor editor;
public ScoreDatabase(Context context){
this.context=context;
pref = context.getSharedPreferences("MY_PREFS", Context.MODE_PRIVATE);
editor = pref.edit();
}
public int getFirstScore() {
return pref.getInt("FIRST_SCORE", 0);
}
public int getSecondScore() {
return pref.getInt("SECOND_SCORE", 0);
}
public void setFirstScore(int score) {
editor.putInt("FIRST_SCORE", score);
editor.commit();
}
public void setSecondScore(int score) {
editor.putInt("SECOND_SCORE", score);
editor.commit();
}
}
Now make instance of this class and use anywhere you want just pass getApplicationContext() in the constructor
//In your MainActivity class
ScoreDatabase scoreDatabase=new ScoreDatabase(getApplicationContext());
//call set function when you want to set score
scoreDatabase.setFirstScore(10);
scoreDatabase.setSecondScore(20);
//Call get function when you want to get score
int firstScore=scoreDatabase.getFirstScore();
int secondScore=scoreDatabase.getSecondScore();

How to count time in two different activities?

I don't know if this is even possible but I have several activities, two at the moment, and I have time limit of 20 minutes for player to finish the game. The problem is, he starts at one activity, then goes to another and so on. How to keep the timer going even in another activity, and keep it visible in a textView?
EDIT for minhaz:
public void getTime(long value, String PREFERENCE_NAME){
SharedPreferences myPrefs = mContext.getSharedPreferences(PREFERENCE_NAME, Context.MODE_PRIVATE);
SharedPreferences.Editor prefsEditor = myPrefs.edit();
prefsEditor.putLong("time", value);
prefsEditor.commit();
}
Just create a global timer class.
class Timer {
private static long startTime = -1;
public static void reset() {Timer.startTime = -1;}
public static void initialize() {Timer.startTime = System.currentTimeMillis();}
public static long getTimeMillis() {return System.currentTimeMillis() - startTime;}
private Timer() {}
}
Then, by importing this class (wherever you've put it), you can access the current time.
As stated by Lukas, extending Application would be nice.
You could also use a preference that store the time at which the timer was started...
But working working with timer start time sounds the best way, I think.
Start timer from one activity and when user switch to next one pass the value inside an Intent
Intent intent=new Intent(Current.class, NextActivity.class);
intent.putExtra("time", timer_value);
And on the another activity get the value as
time_value=intent.getLongExtra("time")
In this way user will get some buffer time, when their is delay in between activities, as starting activity call is Asynchronous. You can call finsh() or do something else based on your requirement from the time.
Extending Application class is also a good solution, if you want to limit time from starting the app. But thats not exactly the total play time.
Update:
For storing data, you can use persistence storage based on your requirement. Right now, shared preference look like a good candidate.
Store Data
SharedPreferences myPrefs = mContext.getSharedPreferences(PREFERENCE_NAME, Context.MODE_PRIVATE);
SharedPreferences.Editor prefsEditor = myPrefs.edit();
prefsEditor.putLong("time", value);
prefsEditor.commit();
Retrieve data
SharedPreferences sharedPref = mContext.getSharedPreferences(PREFERENCE_NAME, Context.MODE_PRIVATE);
return sharedPref.getLong("time", 0);

Global EditText Variables

I'm writing my first android app, and I have an EditText object that I want to be read across my entire program (multiple activities). I'd like to take in a user's name on one screen/activity/layout and read it in several others to manipulate or display it, so I've found that the string needs to be public and static, and that there should be a class with my global variables. What is the correct way to do this? I've tried using bundles and several other methods, but none seem to work.
You should definitely be passing this value through intents.
Intent intent = new Intent(getApplicationContext(),NEXTCLASS.class);
intent.putExtra("username",mEditText1.getText().toString());
startActivity(intent);
and then to receive it in the next class
Bundle extras = intent.getExtras();
mEditText1.setText(extras.getString("username"))
You could also use shared preferences however I think that is unnecessary for your situation as you do not need the username to persist when the app is closed.
Update:
To use shared prefs..
SharedPreferences sharedPreferences = getSharedPreferences("myprefs", MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putString("username", myusername);
To read from shared prefs...
SharedPreferences sharedPreferences = getSharedPreferences("myprefs", MODE_PRIVATE);
String username = sharedPreferences.getString("username", "");
An example of using a static property
public class utility {
public static String USERNAME = "username";
}
To invoke you do not need to instantiate the class just do this from each class that needs it
String username = sharedPreferences.getString(utility.USERNAME, "")
You can use SharedPreferences to store the value. Read more here.

Categories