I am making a small game and I want to save all the variables (objects and basic types) when closing the app to be able to load the saved game later on.
Here are some of the variables:
String playerName;
Duration time;
Item[] inventory=new Item[20]; //enum
int inventoryTotalItems=0;
It is basically the same situation than save variables after quitting application? or How can I save an activity state using the save instance state? but what I want to save are Objects, so I am not sure I can use the preferences or the Bundle for that.
I also will want to store more than one preference to be able to load different saved games. Can I do this with onPause() and onResume()?
Thanks.
Add this in your dependencies(in build.gradle file):
implementation 'com.google.code.gson:gson:2.8.9'
And then you can save objects like this:
SharedPreferences sp = getPreferences(MODE_PRIVATE);
SharedPreferences.Editor pe = sp.edit();
Gson gson = new Gson();
String j = gson.toJson(myObj);
pe.putString("MyObject", j);
pe.apply();
And when you want to access the object later:
SharedPreferences sp = getPreferences(MODE_PRIVATE);
Gson gson = new Gson();
String j = sp.getString("MyObject", null);
MyObject myObj = gson.fromJson(j, MyObject.class);
I think you should save in onPause().
Related
I'm having doubt and a problem I tried to solve with this Note App I found on Google, which is pretty simple, so I (a beginner) went to try few things on it.
Everytime I save few notes, close app, restart app, it reorganizes the notes alphabetically, which I don't want. I know that Set and ArrayList are different in the sense a Set won't repeat elements, but ArrayList will. Also Set can't guarantee the order when called.
The question is: how is a good way to solve this instrinsecally sorting problem?
I've tried to switch what's HashSet to ArrayList, but the method putStringSet requires a Set in its parameters, which ArrayList isn't.
The following code works (doesn't crash or any other problem) but doesn't work as I want.
I have this part code in the MainActivity
SharedPreferences sharedPreferences = getApplicationContext().getSharedPreferences("com.tanay.thunderbird.deathnote", Context.MODE_PRIVATE);
HashSet<String> set = (HashSet<String>) sharedPreferences.getStringSet("notes", null);
// a lot of other things here
if (set == null) {
notes.add("Example Note");
} else {
notes = new ArrayList<>(set); // to bring all the already stored data in the set to the notes ArrayList
}
On NoteEditorActivity I have
Intent intent = getIntent();
noteID = intent.getIntExtra("noteID", -1);
if (noteID != -1) {
editText.setText(MainActivity.notes.get(noteID));
} else {
MainActivity.notes.add(""); // as initially, the note is empty
noteID = MainActivity.notes.size() - 1;
MainActivity.arrayAdapter.notifyDataSetChanged();
}
//other things here
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
MainActivity.notes.set(noteID, String.valueOf(s));
MainActivity.arrayAdapter.notifyDataSetChanged();
SharedPreferences sharedPreferences = getApplicationContext().getSharedPreferences("com.tanay.thunderbird.deathnote", Context.MODE_PRIVATE);
HashSet<String> set = new HashSet<>(MainActivity.notes);
sharedPreferences.edit().putStringSet("notes", set).apply();
}
If you would like to keep the order of the notes, Array or List is truly the better choice than using Set.
To store this into SharedPreferences, you can refer to Put and get String array from shared preferences
This question has answers explaining the followings:
Jsonify the list and parse it back.
Concatenate all the Strings with delimiter and split it back.
I create a few ArrayLists during one of my activities. When I leave the activity and come back to it, they come up as null. From some research, SharedPreferences is the way to overcome this. How do I go about this; do I have to save it as a HashMap? is SharedPreferences it's own method or do I do it within another specific method?
You have at least three options:
Use a SharedPreferences object as you suggest in your question.
Use a SQLite database.
Use a file with your own format.
For an introduction to each of these options, read Storage Options.
Here, how to write on Shared Preferences:
SharedPreferences sp = getActivity().getPreferences(Context.MODE_PRIVATE);
//if your codes in your activity class, you dont need getActivity so you should use this
SharedPreferences.Editor editor = sp.edit();
editor.putInt("your_string_key", yourValue);
editor.commit();
Here, how to read from Shared Preferences:
SharedPreferences sp = getActivity().getPreferences(Context.MODE_PRIVATE);
//same here. If your codes in your activity don't write "getActivity." part
int yourSavedValue = sp.getInt("your_string_key", defaultValue);
//defaultValue mean if there is no value with that key, it will return defaultValue.
If you'd like to learn more about it here you can get more information.
Answer to your new updated question:
As you can see my answer there is defaultValue.
// Restore preferences
SharedPreferences settings = getSharedPreferences(PREF_FILE, Context.MODE_PRIVATE);
Set<String> tempSet = settings.getStringSet(FIRST_LIST, "");
Set<String> temp2Set = settings.getStringSet(SECOND_LIST, "");
//if it is first time it will return null. So your app going crash. To avoid that make a default value. Like this.
for (String str : tempSet)
firstList.add(Uri.parse(str));
for (String str : temp2Set)
secondList.add(Uri.parse(str));
** you have convert this array to gson.
** First pass your array in parameter public void saveArrayList(ArrayList list, String key)
** now create object of SharedPreferences
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(activity);
SharedPreferences.Editor editor = prefs.edit();
** now convert to gson :
Gson gson = new Gson();
String json = gson.toJson(list);
editor.putString(key, json);
editor.apply(); // This line is IMPORTANT !!!
I want to call class Attributes by variable .
fo example
Billing.SKU_NAME_PREMIUM1
I want:
String a = 'SKU_NAME_PREMIUM1';
Billing.a
edit:
I want to use variable for Attribute name in
SharedPreferences.Editor editor = shared.edit();
editor.putBoolean(Billing.KEY_PREMIUM_VERSION, true);
Because the class Billing has more than 30 attributes and select the attribute at runtime Depending on the user's choice
It looks like you are looking for variables. Now assuming that type of KEY_PREMIUM_VERSION is int we can use
SharedPreferences.Editor editor = shared.edit();
int ver = Billing.KEY_PREMIUM_VERSION;//variable `ver` will
//copy value of Billing.KEY_PREMIUM_VERSION
editor.putBoolean(ver, true);
You can use Class.getField(name). Note: Using reflection is not recommended in production / final code
Object o = ...;
Field f = o.getClass().getField("a");
I am pretty new to the android programming thing so I am sure that there is something simple that I am not doing correctly. I have two activities that are accessing a shared preferences file; one that reads from it and displays the contents to a list, and the other reads the contents and adds a new item to the list based upon user input. The issue that I am having: when I read the contents from the file and attempt to add a new item to the list my original list is being overwritten. Maybe that's not what is actually happening but it seems to me that this is the issue. When I add a new item from the child activity and return to the original activity which displays the list I am only seeing the newest item that I saved and not any other items that I had created previously.
The first activity is the main activity and it simply reads the shared preferences and adds the items in a string, separated by commas and displays them in a listview. I only showed the method for displaying the items in the listview:
public void addItems() {
String strLists="";
SharedPreferences sharedPref = getSharedPreferences("ListNamesFile", MODE_PRIVATE);
strLists = sharedPref.getString(getString(R.string.edit_message), strLists);
listItems.clear();
String[] myLists = strLists.split(",");
for(int r=0;r<myLists.length;r++){
listItems.add(myLists[r].toString());
}
//test adding an extra list item to make sure that the issue isn't from adding
//items to the listview
//listItems.add("test");
adapter.notifyDataSetChanged();
}
The second activity is for getting a new string from an edit text control, adding it to the end of the string with the list items, and committing the changes to the shared preferences file. I have included the method for retrieving the shared preferences and writing the new item to the end of the string:
public void createListOnClick(View view){
//create a file for storing list items
SharedPreferences sharedPref = getSharedPreferences("ListNamesFile", MODE_PRIVATE);
String strMyLists = "";
sharedPref.getString(getString(R.string.edit_message),strMyLists);
String[] lists = strMyLists.split(",");
StringBuilder sb = new StringBuilder();
for (int i = 0; i < lists.length; i++) {
sb.append(lists[i]);
sb.append(",");
}
SharedPreferences.Editor editor = sharedPref.edit();
EditText txtListName = (EditText)findViewById(R.id.txt_list_name);
sb.append(txtListName.getText().toString());
editor.putString(getString(R.string.edit_message), sb.toString());
editor.commit();
finish();
}
It seems that it must be something simple that I am missing but I haven't been able to figure it out so any help would be greatly appreciated.
you still haven't assigned the sharedPref value in the strMyLists.
In the second activity, you're not actually assigning the read shared preferences:
You should replace
sharedPref.getString(getString(R.string.edit_message),strMyLists);
with
strMyLists = sharedPref.getString(getString(R.string.edit_message),strMyLists);
in getString method
sharedPref.getString(getString(R.string.edit_message),strMyLists);
second argument is default value. So you will have to write.
strMyLists = sharedPref.getString(getString(R.string.edit_message),"");
it will work with this. rest of the code is good.
I have created two EditText objects in the Java code of My android application, as
final EditText et1=(EditText)findViewById(R.id.editText1);
final EditText et2=(EditText)findViewById(R.id.editText2);
then on the onClick() event of a button, called a method with parameters as-
addStringToXmlFile(et1.getText(),et2.getText());
now in the definition of this method below, i have written-
private void addStringToXmlFile(Editable editable1,Editable editable2){
String s1=new String();
s1=editable1.toString();
String s2=new String();
s2=editable2.toString();
}
The problem is that, now i want to use these two String objects s1,s2, to make two entries in the res/values/Strings.xml file of the database, & I don't know how to do it.
please guide me further.
This is not possible - an app's apk (including it's resources) can not be changed at runtime. I'm not entirely sure of all of the reasons why, but one obvious thing I can think of is that R.java needs to contain a reference to your String in order for you to access it, and this file is generated by the compiler when you create the APK.
If you need to persist a String across sessions, you should look into using one of several data storage mechanisms that Android provides, such as SharedPreferences.
Take a look into using SharedPreferences to store your string values instead.
//Saving your strings
SharedPreferences prefs = this.getSharedPreferences("myPrefsKey", Context.MODE_PRIVATE);
Editor editor = prefs.edit();
editor.putString("s1", s1);
editor.putString("s2", s2);
editor.commit();
//retrieving your strings from preferences
SharedPreferences prefs = this.getSharedPreferences("myPrefsKey", Context.MODE_PRIVATE);
String s1 = prefs.getString("s1", ""); //empty string is the default value
String s2 = prefs.getString("s2", ""); //empty string is the default value