onSaveInstanceState() - only one passes - java

Update: including actual code
I am using ArrayList to fill a custom adapter and it works fine on orientation change etc.:
"onCreate"
myArrayList = savedInstanceState.getParcelableArrayList(myListkey);
"onSaveInstanceState"
savedInstanceState.putParcelableArrayList(myListkey, myArrayList);
and I can get it out fine
But.. I need to pass multiple variables and then it breaks, it looks like it´s only the one inserted last that I can get.
ex.1
"onCreate"
myNameString = savedInstanceState.getString(namekey);
myArrayList = savedInstanceState.getParcelableArrayList(myListkey);
"onSaveInstanceState"
savedInstanceState.putString(listkey, myNameString);
savedInstanceState.putParcelableArrayList(myListkey, myArrayList);
Here "myArrayList" is filled, but "myNameString" is null
ex. 2
"onCreate"
myArrayList = savedInstanceState.getParcelableArrayList(listkey);
myNameString = savedInstanceState.getString(namekey);
"onSaveInstanceState"
savedInstanceState.putParcelableArrayList(listkey, myArrayList);
savedInstanceState.putString(namekey, myNameString);
Here "myNameString" is filled, but "myArrayList" is null
original code:
#Override
protected void onCreate(Bundle savedInstanceState) {
if (savedInstanceState != null) {
_listName = savedInstanceState.getString(getApplicationContext().getResources().getString(R.string.saved_instance_list_name));
_listItems = savedInstanceState.getParcelableArrayList(getApplicationContext().getResources().getString(R.string.saved_instance_list_items_edit));
}
... more code
}
#Override
public void onSaveInstanceState(Bundle savedInstanceState) {
super.onSaveInstanceState(savedInstanceState);
savedInstanceState.putString(getApplicationContext().getResources().getString(R.string.saved_instance_list_name), _listName);
savedInstanceState.putParcelableArrayList(getApplicationContext().getResources().getString(R.string.saved_instance_list_items_edit), _listItems);
}

Related

LinkedHashSet does not main insertion order?

I am currently building an Android app where I display quotes from famous people. I have a home screen and 2 other screens, where I am displaying all quotes and the other where I display favourite quotes.
So, when I hit the like button in the screen of AllQuotesActivity the quote and author will be saved in a LinkedHashSet, which will be saved in SharedPreferences, so my FavouriteQuotes Activity can obtain the data. I can obtain the data, but the data is mixed, even though other links say that LinkedHashSet maintains the insertion order. Maybe I did something wrong. Here are the important code snippets:
AllQuotesActivity.java:
SharedPreferences sharedPref;
Set<String> set = new LinkedHashSet();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.all_quotes);
Resources res = getResources();
Context context = getApplicationContext();
this.sharedPref = context.getSharedPreferences(
"MyPref", Context.MODE_PRIVATE);
final String[] quotesAndAuthors = res.getStringArray(R.array.quotes);
button3.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
set.add(quotesAndAuthors[counter]);
set.add(quotesAndAuthors[counter + 1]);
}
});
}
#Override
public void onPause() {
super.onPause();
Log.d("RichQuotes", "Its paused mkay");
Editor editor = sharedPref.edit();
editor.putStringSet("quotesAndAuthors", this.set);
editor.commit();
}
}
FavouriteQuotesActivity.java:
SharedPreferences sharedPref;
Set<String> set = new LinkedHashSet();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.favourite_quotes);
Resources res = getResources();
Context context = getApplicationContext();
this.sharedPref = context.getSharedPreferences(
"MyPref", Context.MODE_PRIVATE);
set = sharedPref.getStringSet("quotesAndAuthors", null);
for (Iterator<String> it = set.iterator(); it.hasNext(); ) {
String s = it.next();
Log.v("test", s);
}
I removed unnecessary code.
In the FavouriteQuotesActivity.java I am logging the set to check its values. The log-outputs and the outputs on the screen are the same, both unsorted the same way.
Set set = new LinkedHashSet();
In this line, you instantiate a new empty LinkedHashSet object. This object was then assigned to the variable named set.
set = sharedPref.getStringSet("quotesAndAuthors", null);
In this line, you reassigned the set variable to point to some other object, some Set object returned by your call to getStringSet. We do not know the concrete class of this second object that implements the Set interface. You can ask by calling getClass.
Your first set, the empty LinkedHashSet, went unused. With no other references pointing to it, that set became a candidate for eventual garbage-collection.

android SaveInstance in activity and garbage collector

Currently I am working on the second version of my vocabulary app. The first version does not provide as much documentation to expand the application. so I decided to start from the ground up.
I have an activity, every time I send it to background and then get it back to foreground, some objects became null and activity restarts. In onResume, I logged the value of the null object.
The old activity (version 1) does not have that problem.
I tried avoid that null problem whilst saving activities states and objects to SaveInstanceState and restore them. but RestoreInstance was never called.
here is my code
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_query);
Log.e(TAG, "onCreate");
/* Initialize DATA */
data = new DataHandler(this);
/* Initialize VIEWS */
btnPhase = findViewById(R.id.query_voc_phase);
cardPath = findViewById(R.id.query_voc_path);
queryView = findViewById(R.id.query_view);
btnShow = findViewById(R.id.query_btn_show_answer);
btnRight = findViewById(R.id.query_btn_mark_right);
btnWrong = findViewById(R.id.query_btn_mark_wrong);
btnNext = findViewById(R.id.query_btn_show_next);
}
#Override
protected void onStart() {
super.onStart();
Log.e(TAG, "onStart");
/* set OnClickListener */
btnShow.setOnClickListener(this);
btnRight.setOnClickListener(this);
btnWrong.setOnClickListener(this);
btnNext.setOnClickListener(this);
//init Variables
queryList = new ArrayList<>();
idList = new ArrayList<>();
listGroupings = new ArrayList<>();
answeredList = new ArrayList<>();
//init Preferences
preferences = PreferenceManager.getDefaultSharedPreferences(this);
//set Visibility of view items based on Preferences
if (!preferences.getBoolean(Preferences.SHOW_CARD_PATH_ENABLED, true))
cardPath.setVisibility(View.GONE);
//load preferences
userID = preferences.getInt(Preferences.CURRENT_USER, -1);
//check if flashing card is enabled and get time
flash_time = preferences.getBoolean(Preferences.FLASH_CARD_ENABLED, false) ? preferences.getInt(Preferences.FLASH_TIME, flash_time) : -1;
//get data from intent
Intent intent = getIntent();
if (intent.hasExtra(QUERY_CONTAINER_LIST)) {
//get data into the list
HashMap<String, ArrayList<Integer>> queryData = data.getCardsToQuery(intent.getStringArrayListExtra(QUERY_CONTAINER_LIST));
idList = queryData.get("iList");
listGroupings = queryData.get("listGroupings");
}
// change active Fragment to initial fragment
changeFragment(QueryViews.Simple);
}
#Override
protected void onResume() {
super.onResume();
Log.e(TAG, "onResume");
Log.e(TAG, "current card is null " + (currentCard == null));
//loads a new card if there is none
if(currentCard == null) loadNext();
}
/*
InstanceState
*/
#Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
Log.e(TAG, "RESTORE");
queryList = savedInstanceState.getParcelableArrayList("queryList");
idList = savedInstanceState.getIntegerArrayList("iList");
listGroupings = savedInstanceState.getIntegerArrayList("listGroupings");
answeredList = savedInstanceState.getParcelableArrayList("answeredList");
currentCard = (VocabularyCard)savedInstanceState.getSerializable("currentCard");
lastCard = (VocabularyCard)savedInstanceState.getSerializable("lastCard");
}
#Override
protected void onSaveInstanceState(Bundle outState) {
Log.e(TAG, "SAVE");
outState.putParcelableArrayList("queryList", queryList);
outState.putIntegerArrayList("idList", idList);
outState.putIntegerArrayList("listGroupings", listGroupings);
outState.putParcelableArrayList("answeredList", answeredList);
outState.putParcelable("currentCard", currentCard);
outState.putParcelable("lastCard", lastCard);
super.onSaveInstanceState(outState);
}
Spotting below error, maybe it is a typo error, but may be the culprit of your null object issue. You restore iList inside onRestoreInstanceState,
#Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
Log.e(TAG, "RESTORE");
idList = savedInstanceState.getIntegerArrayList("iList");
}
But inside onSaveInstanceState, you put idList,
#Override
protected void onSaveInstanceState(Bundle outState) {
Log.e(TAG, "SAVE");
...
outState.putIntegerArrayList("idList", idList);
...
super.onSaveInstanceState(outState);
}
I found a solution. I found out that onRestoreInstanceState will called if device rotates. First of all if something became null, you should first check if the object was assigned a value. in this case i overlooked, that the object was never assigned a value.

How to fix error with rich text editor(android-RTEditor)?

I would like to use RTEditor in my app. but I have some errors in code. My question is what can I do with that? Instruction about RTEditor is here: https://github.com/1gravity/Android-RTEditor
and that's part of my code:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setTheme(R.style.RTE_BaseThemeDark);
setContentView(R.layout.activity_editor);
newRowEdit = (EditText) findViewById(R.id.editNote);
newRowEdit1 = (EditText) findViewById(R.id.rtEditText);
// create RTManager
RTApi rtApi = new RTApi(this, new RTProxyImpl(this), new RTMediaFactoryImpl(this, true));
RTManager rtManager = new RTManager(rtApi, savedInstanceState);
// register toolbar
ViewGroup toolbarContainer = (ViewGroup) findViewById(R.id.rte_toolbar_container);
RTToolbar rtToolbar = (RTToolbar) findViewById(R.id.rte_toolbar);
if (rtToolbar != null) {
rtManager.registerToolbar(toolbarContainer, rtToolbar);
}
// register editor & set text
RTEditText rtEditText = (RTEditText) findViewById(R.id.rtEditText);
rtManager.registerEditor(rtEditText, true);
rtEditText.setRichTextEditing(true, message);
String text = rtEditText.getText(RTFormat.HTML);
}
Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
mRTManager.onSaveInstanceState(outState);
}
#Override
public void onDestroy() {
super.onDestroy();
mRTManager.onDestroy(isFinishing());
}
The error is: cannot resolve symbol: message and cannot resolve symbol:mRTManager.
Can anyone help me please?
I can't see the whole code but it seems that both variables are not declared inside the corresponding methods. Make sure they are declared as class member variables
Replace mRTManager with rtManager, and make sure rtManager is declared outside onCreate method.

Keeping list entries when I move activity

I have a ListView.
I populate this list from 2 editTexts
When I move activity and go back to it the entries are gone again.
I kind of understand why this is but dont know how to correct it.
ListView lv2 = (ListView) findViewById(R.id.listView2);
final SimpleAdapter simpleAdpt = new SimpleAdapter(this, planetsList, android.R.layout.simple_list_item_1, new String[]{"planet"}, new int[]{android.R.id.text1});
planetsList.add(createPlanet("planet", "testme"));
lv2.setAdapter(simpleAdpt);
button21.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
iinitList();
simpleAdpt.notifyDataSetChanged();
editText5.setText("");
editText6.setText("");
}
});
}
private void iinitList() {
String st,str;
Double db;
if (editText5.getText().toString()!= "" && editText6.getText().toString()!="") {
st = editText5.getText().toString();
str = editText6.getText().toString();
db = Double.parseDouble(str);
planetsList.add(createPlanet("planet", ""+st+
": \n" +db+""));
}
}
HashMap<String, String> createPlanet(String key, String name) {
HashMap<String, String> planet = new HashMap<String, String>();
planet.put(key, name);
return planet;
}
As you can see I have added a value to the list manually called test also, when I move activity this stays in the list, I would love if the editText entries were to stay in there also when I move activities.
Activities can be destroyed when you navigate to a new one or rotate. This will clear anything that is only referenced by the activity, like your EditTexts. However, Android provides a nice utility for saving things you want to remain in a method called, which you can override in your activity:
#Override
protected void onSaveInstanceState(Bundle state) {
// Put your values in the state bundle here
}
#Override
protected void onCreate(Bundle savedState) {
// Load your UI elements as usual
if (savedState != null) {
// Load your state from the bundle
}
}
That same bundle will be given back to you in onCreate, where you create your UI to begin with so you can reload the state from it.
This is a really good description of how activities work:
http://developer.android.com/reference/android/app/Activity.html

notifyDataSetChanged() not working in ListFragment

I have a ListView in a ListFragment that is populated via a database query. It loads all the data just fine when it first populates the list in onCreate(). But when I requery the database, assign the return value to assignmentsCursor, and call notifyDataSetChanged(), it doesn't update adapter.mCursor. If I go into the Debugging mode in Eclipse I can see that assignmentsCursor.mCount has changed, but when I look at adapter.mCursor.mCount, it's the same as before. (Yes, I'm checking after notifyDataSetChanged() has been called.)
The relevant parts of my code:
SimpleCursorAdapter adapter;
Cursor assignmentsCursor;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (savedInstanceState != null) {
course = savedInstanceState.getShort(Values.ASSIGNMENT_KEY_COURSE);
}
setRetainInstance(true);
// Create and array to specify the fields we want
String[] from = new String[] { Values.KEY_TITLE, Values.ASSIGNMENT_KEY_COURSE };
// and an array of the fields we want to bind in the view
int[] to = new int[] { R.id.assignment_list_title, R.id.assignment_list_course };
// Need to give assignmentsCursor a value -- null will make it not work
updateAdapter();
adapter = new SimpleCursorAdapter(context, R.layout.assignment_list_item, assignmentsCursor, from, to);
setListAdapter(adapter);
}
public void onResume() {
super.onResume();
updateAdapter();
refresh();
}
/**
* Updates the content in the adapter.
*/
public void updateAdapter() {
SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(context);
boolean showingCompleted = sharedPrefs.getBoolean(Values.ASSIGNMENT_KEY_SHOWING_COMPLETED, false);
if (course < 0) // Showing assignments from all courses
if (showingCompleted)
assignmentsCursor = DbUtils.fetchAllAssignments(context, Values.ASSIGNMENT_LIST_FETCH, null, true);
else
assignmentsCursor = DbUtils.fetchIncompleteAssignments(context, Values.ASSIGNMENT_LIST_FETCH, null, true);
else // Showing assignments from specified course
if (showingCompleted)
assignmentsCursor = DbUtils.fetchAllAssignments(context, Values.ASSIGNMENT_LIST_FETCH, course, true);
else
assignmentsCursor = DbUtils.fetchIncompleteAssignments(context, Values.ASSIGNMENT_LIST_FETCH, course, true);
}
private void refresh() {
updateAdapter();
adapter.notifyDataSetChanged();
}
Help me!! ;)
P.S. If you need any more details/code, just let me know. I am positive that the database is querying correctly though.
Thanks to Deucalion, I have determined that I incorrectly assumed that the adapter was referencing the assignmentsCursor variable as opposed to creating a copy of the Cursor for itself. What I needed to do was just call adapter.changeCursor(assignmentsCursor) so that it updated its local copy. Thanks again Deucalion!

Categories

Resources