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.
Related
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.
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();
I'm wanting to save the value of strings (numeral Strings) to somewhere where i can when the user reloads the app, the values can be passed back into the app. Being saved to local storage is preferrable
I would suggest using shared preferences over a SQLLite DB if you are only saving a small amount of strings.
private void saveStringToPreferences(String key, String str){
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
SharedPreferences.Editor editor = preferences.edit();
editor.putString(key, str);
editor.apply();
}
private void getStringFromPreferences(String key){
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
String previousText = preferences.getString(key, "");
return previousText;
}
You really should do some research before asking such a question. Here is a link to the options available for storing data in android:
http://developer.android.com/guide/topics/data/data-storage.html
On my SettingsActivity i am saving a value with the following code:
SharedPreferences.Editor editor = getPreferences(MODE_PRIVATE).edit();
editor.putString("ClassName", strArrClasses.get(i));' // i is a variable inside a loop
int intClassID = i+1;
editor.putInt("ClassID", intClassID);
editor.commit();
I'm now trying to get the value of the SharedPreference with the Key "ClassID" on my MainActivity with the following code:
SharedPreferences sharedPrefs = getPreferences(MODE_PRIVATE);
int intClassID = sharedPrefs.getInt("ClassID", 543548564);
My problem now is that I cant access the class ID and I am always getting the default value.
Edit:
I already checked if i can get the ClassID on my SettingsActivity and that works well
use getSharedPreferences instead. Like
SharedPreferences sharedPrefs = getSharedPreferences(name, MODE_PRIVATE);
as from document here
getPreferences retieves a SharedPreferences object for accessing
preferences that are private to this activity. This simply calls the
underlying getSharedPreferences(String, int) method by passing in this
activity's class name as the preferences name.
and getSharedPreferences retrieve SharedPreference by the name.
In your case you used getPreferences which returned SharedPreferences of those activities only.
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.