Values are'nt saved in onSaveInstanceState while leaving the activity - android

I am trying to save values while leaving from activity and retrieve when coming back to screen.
So I'm using onSaveInstanceState method to save data and using Bundle object from onCreate method while coming back.
Below is my scenario..
Activity A:
protected void onCreate(Bundle savedInstanceState) {
if (savedInstanceState != null) {
Log.d(TAG, "Object received from savedInstanceState");
}
else{
Log.d(TAG, "savedInstanceState value is null");
}
}
public void onSaveInstanceState(Bundle savedInstanceState) {
super.onSaveInstanceState(savedInstanceState);
Log.d(TAG, "In onSaveInstanceState");
savedInstanceState.putString("obj_name", DashBoardDisplay_l.getName());
}
OnClickListener save_click = new OnClickListener() {
#Override
public void onClick(View arg0) {
Intent i = new Intent(getApplicationContext(),PointLogActivity.class);
i.putExtra("ref_name", Name_ref);
startActivity(i);}};
I could see the log for onSaveInstanceState method while leaving to PointLogActivity.
PointLogActivity:
#Override
protected void onCreate(Bundle savedInstanceState){
Intent intent = getIntent();
String YourtransferredData = intent.getExtras().getString("ref_name");
Log.d(TAG, "ref name "+YourtransferredData);
Name=YourtransferredData;
//For getting back button
getActionBar().setDisplayHomeAsUpEnabled(true);
}
I am coming back to Activity A by click back button in top left of the activity.
But while coming back to Activity, I could not find date from Bundle object and getting log from null condition.
savedInstanceState value is null
So can someone tell where I am going wrong.

I resolved it by putting the below at parent activity in manifest file.
android:launchMode="singleTop">

Related

How to keep intent for second activity?

I have a MainActivity with some cards which have different names. onClick, the title is passed as an intent via the adapter to the secondActivity and displayed as the header. From there, I can go to other activities. If I come back from one of these other activities (via the back button created by establishing second activity as the parent activity) the header is gone. How do I keep the header that was originally passed on as an intent or should I go about this completely different?
I have tried using onResume() and onStart() in the secondActivity to reassign the intent from a global variable.
The adapter class, where the card onClick method is written:
#Override
public void onBindViewHolder(final TripHolder tripHolder, final int position) {
Trip trip = trips.get(position);
tripHolder.setDetails(trip);
tripHolder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(context, SecondActivity.class);
TextView card_title = v.findViewById(R.id.TripNamecl);
intent.putExtra("card_title", card_title.getText().toString());
context.startActivity(intent);
}
});
}
The secondActivity where the header should be displayed:
public class SecondActivity extends AppCompatActivity {
String name;
TextView header;
static final String STATE_HEADER = "header";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second);
name = getIntent().getStringExtra("card_title");
header = findViewById(R.id.TripsHeader);
header.setText(name);
}
#Override
public void onSaveInstanceState(Bundle savedInstanceState) {
super.onSaveInstanceState(savedInstanceState);
savedInstanceState.putString(STATE_HEADER, name);
}
#Override
public void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
name = savedInstanceState.getString(STATE_HEADER);
header.setText(name);
}
public void launchMapsActivity(View view) {
Uri gmmIntentUri = Uri.parse("geo:48.8566°,2.3522");
Intent mapIntent = new Intent(Intent.ACTION_VIEW, gmmIntentUri);
mapIntent.setPackage("com.google.android.apps.maps");
if (mapIntent.resolveActivity(getPackageManager()) != null) {
startActivity(mapIntent);
}
}
public void launchTravelActivity(View view) {
Intent intent = new Intent(this, TravelActivity.class);
startActivity(intent);
}
public void launchPlansActivity(View view) {
Intent intent = new Intent(this, PlansActivity.class);
startActivity(intent);
}
}
SOLUTION:
The solution was to put android:launchMode="singleTop" into the manifest file for the secondactivity. It's described in more detail here: How can I return to a parent activity correctly?
In order to do it you should override onSavedInstanceState in your SecondActivity.
You can use something like that, obv adapt it to your needs:
#Override
public void onSaveInstanceState(Bundle savedInstanceState) {
super.onSaveInstanceState(savedInstanceState);
//here you can save your variables
savedInstanceState.putString("myHeader", name);
}
#Override
public void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
//here you can retrieve your variables
name = savedInstanceState.getString("myHeader");
}
Let me know if this worked! good luck
remove header.setText(name); from onResume and onStart methods
If you want to save data in first activity between lifecicle method calls you have to save your data in Bundle object.
Override method onSaveInstanceState(Bundle bundle) of your activity:
#Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putInt("AStringKey", variableData);
outState.putString("AStringKey2", variableData2);
}
And also override Activity method onRestoreInstanceState(Bundle savedInstanceState):
#Override
protected void onRestoreInstanceState(Bundle savedInstanceState){
super.onRestoreInstanceState(savedInstanceState);
variableData = savedInstanceState.getInt("AStringKey");
variableData2 = savedInstanceState.getString("AStringKey2");
setYourHeaderMethodExample(variableData2)
}
When coming back from third activity to second activity onStart() and onResume() method call executes. Try not using onStart() and onResume() for setting the header and use onCreate method for setting the header.
onCreate() method executes only once in its lifetime, but onStart() and onResume() will execute whenever the activity comes to screen. So when coming back from third activity we don't have any values in the intent.
In your second activity's onCreate method add:
getSupportActionBar().setHomeButtonEnabled(true);
and override the onOptionsItemSelected() method in the class and add the following code:
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()){
case android.R.id.home:
finish();
return true;
}
return super.onOptionsItemSelected(item);
}
You don't need to override the onStart() and onResume() methods.

Getting null pointer exception on when coming back to activity from another activity

I have a problem with saving state and restoring it. I have two variables that I want to save when another activity is started and restore them when I press home back button. There is no problem when I'm pressing soft back button. I'm getting null pointer exception on bundle.getString() method.
Thanks in advance.
if (savedInstanceState != null)
{
cat_id = savedInstanceState.getString("CATEGORY_ID");
cat_name = savedInstanceState.getString("CATEGORY_NAME");
}
else
{
Bundle extras = getIntent().getExtras();
cat_id = extras.getString("CATEGORY_ID"); //here I'm getting an exception
cat_name = extras.getString("CATEGORY_NAME");
}
#Override
protected void onSaveInstanceState(Bundle outState)
{
outState.putString("CATEGORY_ID", state_category_id);
outState.putString("CATEGORY_NAME", state_category_name);
super.onSaveInstanceState(outState);
}
#Override
protected void onSaveInstanceState(Bundle outState)
{
outState.putString("CATEGORY_ID", state_category_id);
outState.putString("CATEGORY_NAME", state_category_name);
super.onSaveInstanceState(outState);
}
And Retrieve data after getting back from different activity :
#Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
if (savedInstanceState != null) {
if (savedInstanceState.containsKey("CATEGORY_ID")) {
cat_id = extras.getString("CATEGORY_ID");
}
if (savedInstanceState.containsKey("CATEGORY_NAME")) {
cat_name = extras.getString("CATEGORY_NAME");
}
}
super.onRestoreInstanceState(savedInstanceState);
}
put this condition in else part
if(getIntent().hasExtra("CATEGORY_ID"))
cat_id = extras.getString("CATEGORY_ID");
else
cat_id=//assign default id
if(getIntent().hasExtra("CATEGORY_NAME"))
cat_name = extras.getString("CATEGORY_NAME");
else
cat_name=//assign default name
Thanks everyone for your support.
Actually I solved problem by storing needed data in static variables and getting them when bundle is null.
Thanks again.

Saving the state of my App through rotation

I am building a memory game app for a java class and i need to save which words are displayed through rotation of the device...the widgets that need to be saved and passed to the new onCreate() method are button widgets that i used setText to display the words that are being shown....can i save and pass the entire state of the application...here is my code that is obviously not working and i was hoping i could get some insight...thanks...here is my code..
private Bundle myBundle = new Bundle();
.....
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_eight);
if(savedInstanceState != null) {
savedInstanceState = myBundle;
}
......
#Override
public void onSaveInstanceState(Bundle savedInstanceState) {
super.onSaveInstanceState(savedInstanceState);
myBundle = savedInstanceState;
}
You got the semantics of using the Bundle backwards. You don't ever want to save the Bundle (or overwrite it). Just use it to serialize your own state variables into it and out of it. For example, if you want to preserve two integer variables and a string between a rotation (such that you can re-initialize the view with these members later), you could do the following:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_eight);
if(savedInstanceState != null) {
// Restore our member variables that represent activity state right here from the passed in Bundle.
_x = savedInstanceState.getInt("MyApp.X", 0);
_y = savedInstanceState.getInt("MyApp.Y", 0);
_name = savedInstanceState.getString("MyApp.NAME", "player");
// not shown - initializing the view elements with the initialized member variables.
}
......
#Override
public void onSaveInstanceState(Bundle savedInstanceState) {
// save our activity state by adding our member variables that represent activity state into the Bundle.
savedInstanceState.putInt("MyApp.X", _x);
savedInstanceState.putInt("MyApp.Y", _y);
savedInstanceState.putString("MyApp.NAME", _name);
// call the parent method *after* you have saved your state
super.onSaveInstanceState(savedInstanceState);
}
Bundle also supports arrays of simple types.
In method onSaveInstanceState add values which you want to save like below
#Override
public void onSaveInstanceState(Bundle savedInstanceState) {
savedInstanceState.putString("key","your string here");
}
and inside oncreate
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if( savedInstanceState != null ) {
System.out.println(savedInstanceState .getString("key"));
}
}

Is it save to overrwrite the savedInstanceState bundle after passing it up?

I have the following (to avoid checking if a fragment is being created newly or just being recreated)
#Override public void onActivityCreated(Bundle args) {
super.onActivityCreated(args);
if (this.getArguments() != null) args = this.getArguments();
// rest of fragment loading goes here
}
Not sure what you are trying to do never seen budle values being overwritten.
If you want some values to be availbale inside fragment pass those values to activity and inside fragment call getActivity().getIntent().getExtra(
Otherwise have a look at code below if want save some fragment data if fragment is destroyed
Inside fragment in onCreate method check if savedInstanceState is null or not
#Override
public void onCreate(Bundle savedInstanceState) {
if (savedInstanceState != null) {
//fragment recreated
}
}
Save data as follows
#Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
if (jsonObject != null) {
outState.putString(Constants.JSON, jsonObject.toString());
}
}

ProgressBarIndeterminateVisibility reappears on change rotation

i have a problem with my app. if i click the button to stop the ProgressBarIndeterminate in actionbar, when i rotate the screen it reappear. can i stop it forever? thanks
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
setContentView(R.layout.activity_main);
setProgressBarIndeterminateVisibility(true);
}
public void test(View v) {
setProgressBarIndeterminateVisibility(false);
}
sorry for my english
When you rotate your screen, the Activity gets created again (onCreate will get invoked again), so you will call setProgressBarIndeterminateVisibility(true) which will make it reappear.
To keep track of whether or not you've clicked the stop button, you will need to save the state somehow (consider implementing onSaveInstanceState and then retrieving the stored value in onCreate, or saving the state to a shared preference/database).
onSaveInstanceState --> invoked when your Activity is torn down due to the rotation
private boolean showProgressBarVisibility = true; //always show the first time
#Override
public void onCreate(Bundle savedInstanceState){
if(savedInstanceState != null && savedInstanceState.containsKey("user3744384_pressed_the_button"){
showProgressBarVisibility = false
}
setProgressBarIndeterminateVisibility(showProgressBarVisibility);
}
#Override
public void onSaveInstanceState(Bundle outState){
super.onSaveInstanceState(outState);
outState.putString("user3744384_pressed_the_button", true);
}
do something like this in onCreate:
if(savedInstanceState !=null){
setProgressBarIndeterminateVisibility(false);
}
but you should also save the state in public void onSaveInstanceState(Bundle ...).. research on how activities save their state.
when orientation changes android kills your activity and onCreate is called.. you can save your app state and restore it.
override this method to save state
#Override
public void onSaveInstanceState(Bundle savedInstanceState) {
savedInstanceState.putString(key, yourstatevariable);
}
and get your state variable in onCreate
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_one);
if (savedInstanceState != null) {
String yourstatevariable = savedInstanceState.get(key);
}
}

Categories

Resources