Persist RecycyclerViewAdapter data on activity recreation - android

I have an Activity with a Fragment inside.
In that fragment there are RecyclerView, and RecyclerViewAdapter.
In fragment's onCreate I'm doing this:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.d("TAGGG", "onCreate: ");
// Database handler
Contract.DbHelper dbHelper = new Contract.DbHelper(getContext());
dERecyclerViewAdapter.setEntries(dbHelper.readAllEntries());
}
Everytime the Activity is recreated(up navigation, rotation changes) data is being read again from the database.
What is the correct way to store it?

You can use the savedInstanceState to store the data through a bundle. You can store it like this
#Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
//Use the bundle to store data
}
And retrieve it like this
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if(savedInstanceState!=null)
{
//Use the savedInstanceState to get the stored result
}
}
Hope this helps !

You should look at the CursorLoader class. Your situation is exactly what this class was intended for.
The loader itself can persist between configuration changes, so that when you call onCreate, if the loader has already performed the query it will just provide the data it already read rather than re-query the database.
See https://developer.android.com/guide/components/loaders.html
Also http://www.androiddesignpatterns.com/2012/07/understanding-loadermanager.html

Related

state of app after 2 rotations

i have been through this documentation regarding the topic save a state before the foreground activity will be destroyed...
and everything works really good now (after a device rotation), but when i rotate my device again after a rotation, i will loose my data again :(
here is my code
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final MainActivity activity = this;
activity.setTitle("Cow Counter");
TextView QntyResultField = findViewById(R.id.textView);
QntyResultField.setText(Integer.toString(cowQnty));
}
// invoked when the activity may be temporarily destroyed, save the instance state here
#Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putInt("qnty", cowQnty);
}
// How we retrieve the data after app crash...
#Override
public void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
//cowQnty = savedInstanceState.getInt("qnty");
TextView QntyResultField = findViewById(R.id.textView);
QntyResultField.setText("Cows: "+Integer.toString(savedInstanceState.getInt("qnty")));
}
I think the solution will be maybe to implement a check if an instance state was already restored before...
i have tried then this here:
if(savedInstanceState.getInt("qnty") != 0){
TextView QntyResultField = findViewById(R.id.textView);
QntyResultField.setText("Cows: "+Integer.toString(savedInstanceState.getInt("qnty")));
}
buit then my inital part in my onCreate() method will write a zero in my result field
TextView QntyResultField = findViewById(R.id.textView);
QntyResultField.setText(Integer.toString(cowQnty));
Could anyone tell me if I am close to the solution?
You use a variable called cowQnty to store the value that is then saved in the bundle for your onSaveInstanceState as outState.putInt("qnty", cowQnty);, then when you restore it in onRestoreInstanceState you only set the TextView's value to the retrieved value and do not update the value for cowQnty.
How do you expect then to save an empty field again? There are two solutions to this;
Firstly, if cowQnty is not a sizeable amount and you do not mind using a tad of RAM, make cowQnty a static field and it will persist the data without needing to save it in a Bundle at all.
Secondly, just set cowQnty's value once again when you restore your state (why did you comment it out??), like so:
#Override
public void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
cowQnty = savedInstanceState.getInt("qnty");
TextView QntyResultField = findViewById(R.id.textView);
QntyResultField.setText("Cows: "+Integer.toString(savedInstanceState.getInt("qnty")));
}

SaveInstanceState on ListView objects

I have an activity that perform a search of movies and parse the JSON results into "Movie" Objects.
after the parsing the Movie objects are being inserted into a ListView Adapter.
When i change oriantation the activity restarts and the results are gone.
How can i prevent this from happen or save the Objects and restore them onRestoreInstanceState?
I have already tried onConfigurationChanged.
You need to do a little bit of refactoring.
First implement onSaveInstanceState and save your list to a bundle
#Override
protected void onSaveInstanceState (Bundle outState){
outState.putSerializable("mylist", mylist);
}
Then on your OnCreate check if your bundle has the list and opulate your listview without fetching again your list
#Override
protected void onCreate (Bundle savedInstanceState){
super.onCreate(savedInstanceState);
if(savedInstanceState!=null && savedInstanceState.getSerializable("mylist")!=null){
populateListView(savedInstanceState.getSerializable("mylist"));
}else{
fetchList();
}
}

Save Checkboxes state in ListView and Retrieve it back when come back to class using Shared preferences

I Got stucked in saving the Checkboxes state and getting back in listview, i want to save what all the items were checked and save it and get it back when the Activity is called again... Pls help me in this with sample code... any help will be very usefull for me.
Here is the sample code(But not using sharedPreferences)
public class SavedInstanceDemo extends Activity{
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//retrieve values from savedInstanceState
Boolean isChecked=savedInstanceState.getBoolean("isChecked",false);
}
#Override
public void onSaveInstanceState (Bundle outState){
//save your requires values into this outState which can be retrieved on next time
outState.putBoolean("isChecked", true);
}
}

How to use onSavedInstanceState example please

I'm confused when it comes down to saving a state. So I know that onSaveInstanceState(Bundle) is called when the activity is about to be destroyed. But how do you store your information in it and bring it back to its original state in onCreate(Bundle savedInstanceState)? I don't understand how this bundle will restore information. It would be helpful if someone can provide an example.
The Dev guide doesn't do a good job of explaining this.
public class Conversation extends Activity {
private ProgressDialog progDialog;
int typeBar;
TextView text1;
EditText edit;
Button respond;
private String name;
private String textAtView;
private String savedName;
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.dorothydialog);
text1 = (TextView)findViewById(R.id.dialog);
edit = (EditText)findViewById(R.id.repsond);
respond = (Button)findViewById(R.id.button01);
if(savedInstanceState != null){
savedInstanceState.get(savedName);
text1.setText(savedName);
}
else{
text1.setText("Hello! What is your name?");
respond.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
name = edit.getText().toString();
text1.setText("Nice to meet you "+ name);
}
});
}
}
#Override
public void onSaveInstanceState(Bundle outState){
super.onSaveInstanceState(outState);
outState.putString(savedName, name);
}
}
The Bundle is a container for all the information you want to save. You use the put* functions to insert data into it. Here's a short list (there are more) of put functions you can use to store data in the Bundle.
putString
putBoolean
putByte
putChar
putFloat
putLong
putShort
putParcelable (used for objects but they must implement Parcelable)
In your onCreate function, this Bundle is handed back to the program. The best way to check if the application is being reloaded, or started for the first time is:
if (savedInstanceState != null) {
// Then the application is being reloaded
}
To get the data back out, use the get* functions just like the put* functions. The data is stored as a name-value pair. This is like a hashmap. You provide a key and the value, then when you want the value back, you give the key and the function gets the value. Here's a short example.
#Override
public void onSaveInstanceState(Bundle outState) {
outState.putString("message", "This is my message to be reloaded");
super.onSaveInstanceState(outState);
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (savedInstanceState != null) {
String message = savedInstanceState.getString("message");
Toast.makeText(this, message, Toast.LENGTH_LONG).show();
}
}
Your saved message will be toasted to the screen.
One major note that all new Android developers should know is that any information in Widgets (TextView, Buttons, etc.) will be persisted automatically by Android as long as you assign an ID to them. So that means most of the UI state is taken care of without issue. Only when you need to store other data does this become an issue.
From Android Docs:
The only work required by you is to
provide a unique ID (with the
android:id attribute) for each widget
you want to save its state. If a
widget does not have an ID, then it
cannot save its state
A good information: you don't need to check whether the Bundle object is null into the onCreate() method. Use the onRestoreInstanceState() method, which the system calls after the onStart() method. The system calls onRestoreInstanceState() only if there is a saved state to restore, so you do not need to check whether the Bundle is null
Store information:
static final String PLAYER_SCORE = "playerScore";
static final String PLAYER_LEVEL = "playerLevel";
#Override
public void onSaveInstanceState(Bundle savedInstanceState) {
// Save the user's current game state
savedInstanceState.putInt(PLAYER_SCORE, mCurrentScore);
savedInstanceState.putInt(PLAYER_LEVEL, mCurrentLevel);
// Always call the superclass so it can save the view hierarchy state
super.onSaveInstanceState(savedInstanceState);
}
If you don't want to restore information in your onCreate-Method:
Here are the examples: Recreating an Activity
Instead of restoring the state during onCreate() you may choose to implement onRestoreInstanceState(), which the system calls after the onStart() method. The system calls onRestoreInstanceState() only if there is a saved state to restore, so you do not need to check whether the Bundle is null
public void onRestoreInstanceState(Bundle savedInstanceState) {
// Always call the superclass so it can restore the view hierarchy
super.onRestoreInstanceState(savedInstanceState);
// Restore state members from saved instance
mCurrentScore = savedInstanceState.getInt(PLAYER_SCORE);
mCurrentLevel = savedInstanceState.getInt(PLAYER_LEVEL);
}
Basically onSaveInstanceState(Bundle outBundle) will give you a bundle.
When you look at the Bundle class, you will see that you can put lots of different stuff inside it. At the next call of onCreate(), you just get that Bundle back as an argument.
Then you can read your values again and restore your activity.
Lets say you have an activity with an EditText. The user wrote some text inside it.
After that the system calls your onSaveInstanceState().
You read the text from the EditText and write it into the Bundle via Bundle.putString("edit_text_value", theValue).
Now onCreate is called. You check if the supplied bundle is not null. If thats the case,
you can restore your value via Bundle.getString("edit_text_value") and put it back into your EditText.
This is for extra information.
Imagine this scenario
ActivityA launch ActivityB.
ActivityB launch a new ActivityAPrime by
Intent intent = new Intent(getApplicationContext(), ActivityA.class);
startActivity(intent);
ActivityAPrime has no relationship with ActivityA.
In this case the Bundle in ActivityAPrime.onCreate() will be null.
If ActivityA and ActivityAPrime should be the same activity instead of different activities,
ActivityB should call finish() than using startActivity().
If Data Is not Loaded From savedInstanceState use following code.
The problem is url call is not to complete fully so, check if data is loaded then to show the instanceState value.
//suppose data is not Loaded to savedInstanceState at 1st swipe
if (savedInstanceState == null && !mAlreadyLoaded){
mAlreadyLoaded = true;
GetStoryData();//Url Call
} else {
if (listArray != null) { //Data Array From JsonArray(ListArray)
System.out.println("LocalData " + listArray);
view.findViewById(R.id.progressBar).setVisibility(View.GONE);
}else{
GetStoryData();//Url Call
}
}

Saving state between activities

I have 2 activities named FirstActivity.java and SecondActivity.java.
When I click a button in FirstActivity, I call SecondActivity. When I return back from SecondActivity, based on the result, I need to skip some steps in FirstActivity which are performed in its onCreate() method.
Coming back from SecondActivity I used Bundle to put data which I gave as input to Intent. I accessed that data in onCreate() of first activity .
When I start, activity application was crashing showing as NullPointerException in the line where I am accessing data of 2nd activity.
The reason, I think, is when the application is launched for the first time there are no values in the Bundle
So, can anyone help me in sorting out this issue?
You have to implement the onSaveInstanceState(Bundle savedInstanceState) and save the values you would like to save into a Bundle. Implement onRestoreInstanceState(Bundle savedInstanceState) to recover the Bundle and set the data again:
public class MyActivity extends Activity {
/** The boolean I'll save in a bundle when a state change happens */
private boolean mMyBoolean;
#Override
public void onSaveInstanceState(Bundle savedInstanceState) {
savedInstanceState.putBoolean("MyBoolean", mMyBoolean);
// ... save more data
super.onSaveInstanceState(savedInstanceState);
}
#Override
public void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
mMyBoolean = savedInstanceState.getBoolean("MyBoolean");
// ... recover more data
}
}
Here you will find the usage documentation about the state handling: http://developer.android.com/reference/android/app/Activity.html
Just search for thos methods in the docs :P

Categories

Resources