I'm closing my 2nd activity by clicking on a button, then triggering a "finish()" method. This shall do the same as pressing the back button on my device, and it does.
The problem is that it doesn't enter OnSaveInstanceState, which shall happen when destroying an activity. The result is that after re-entring this activity again, savedInstanceState == null, thus I cannot save my last variables' state.
Button closeButton = (Button) findViewById(R.id.bClose);
closeButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
finish();
From official documentation of the onSaveInstaceState :
Do not confuse this method with activity lifecycle callbacks such as
onPause(), which is always called when an activity is being placed in
the background or on its way to destruction, or onStop() which is
called before destruction. One example of when onPause() and onStop()
is called and not this method is when a user navigates back from
activity B to activity A: there is no need to call
onSaveInstanceState(Bundle) on B because that particular instance will
never be restored, so the system avoids calling it. An example when
onPause() is called and not onSaveInstanceState(Bundle) is when
activity B is launched in front of activity A: the system may avoid
calling onSaveInstanceState(Bundle) on activity A if it isn't killed
during the lifetime of B since the state of the user interface of A
will stay intact.
You have two examples of when the onSaveInstanceState is not called. The most important part is the beginning :
Do not confuse this method with activity lifecycle callbacks such as onPause(), which is always called when an activity is being placed in the background or on its way to destruction.
You should not expects that onSaveInstanceState will be called each time. This method is here to allow the Activity to save its UI elements. If you are trying to persists a variable value or something else (i.e. a value contained inside a View but which should be for the life time of the application - a username for example), you should use another mechanism like SharedPreferences.
Sources
Activity.onSaveInstanceState(Bundle) reference
Related
I'm like an intermediate in android programming. I decided to take a deep dive into the Activity lifecycle methods and I realised something, like why do methods Toasts.show() and many other methods get called again when the activity is resumed. If the methods are in the onCreate so why then if you like go to another activity and return it will still give you a Toast message. Let me give an example.
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
{Your Initialization go here }
//Toas message
Toast.makeText(code).show();
}
}
So imagine you leaving this activity for another one and then coming back... why does it still show the Toast message. Because since the lifecycle is
OnCreate
onResume
onStart
onPause
onstop
onDestroy
And when you come back to your MainActivity it calls the
onResume
onStart.
So if onCreate is not called...So how does the Toast message show.
Please someone should help me answer this I've searched all day but couldn't find answers.
accoording to lifecycle of activity https://developer.android.com/guide/components/activities/activity-lifecycle, if there is no memory engouh the app process will kill, so when you back to your activity on created will call another time.
the image below for clarification:
When your activity goes in the background, and memory is required for other apps. It is possible that the system frees up space even though your activity is in the background with ONPAUSED state. and now if you navigate to your activity, since the saved instance is removed due to memory requirements. instead of ONRESUME, ONSTART is called. you can read more about it here: https://developer.android.com/guide/components/activities/activity-lifecycle
and see this image for better understanding: https://developer.android.com/guide/components/images/activity_lifecycle.png
This uncertainty is one of the reasons why we now mostly use view models for a sizeable app.
I have two activtiy. When a boolean variable in activity 1 is true then the UI in activity 2 should be update (activity 2 is with fragment). When I back to activity 2 with (setDisplayHomeAsUpEnabled) it works correctly but with back button it does not work. What is the difference between this ways and how I can solve this. I try update the activity 2 with this code but it does not work:
#Override
public void onBackPressed() {
super.onBackPressed();
//update();
}
The Home Button is not meant to behave like the Back Button. See this reference. The Home or "Up" Button should take the user up within the view hierarchy (i.e. if you have a number of multiple choice fragments, don't go back through each of them, but back to the activity that started the first fragment)
Each activity should specify what it's parent activity is in order to properly use this functionality. You can do this through the manifest, or by overriding onOptionsItemSelected() as outlined here
In terms of why your activity 2 may be updating when using the "Up" button but not the back button, this could be because both handle the back stack in a different way. Back will take you to the last thing on the stack and resume it, assuming you don't haven't tagged the activity with a launchmode that alters this behavior. Here's more info on the back stack. If you haven't designated your Activity 2 as "singletop" then when you use the "Up" Button, a new instance of that parent activity is created. See here. This may means that the information is updating after using the home button because it's creating a new instance of the activity, while for the back button - you are not creating a new instance but resuming a previous instance... make sure you implement an onResume() function to properly handle this and update the information.
I am developing an Android app in which I want to check if the user has minimized the application or just come from another activity.
In detail, if the user have started another app, went to the home screen or locked the screen, I want to show the activity where the user will enter the password to access the app. But where or how to check this exactly?
https://developer.android.com/guide/components/activities/activity-lifecycle.html
I was trying onResume() but according to documentation onResume() can be fired if the user’s navigating to another activity and coming back.
I'm not very clear on what you are trying to achieve.
The life cycle diagram is quite clear if you are wondering which lifecycle method it would hit when something happens.
Basically, it's the same to minimise the app and go to another activity. But if you are referring to coming from another activity in your own app, you can distinguish your own activity by adding extra information to the intent you use.
Basically, it's like this:
Intent intent = new Intent(FirstActivity.this,SecondActivity.class);
intent.putExtra(key,value);
startActivity(intent);
And in your SecondActivity, you can always retrieve that data like this:
Bundle bundle = getIntent().getExtras();
if ( bundle != null && bundle.containsKey(key) ) {
value = bundle.getInt(key); // not nessecarily getInt(), you should use according to your value type
// use the value to tell if it is from your own app
} else {
// it is not from your own app
}
You can use this mechanism combined with the lifecycle methods. For example, if you use the latter code in your onCreate() method, then whenever the Activity is created, if will check who creates it, which sounds like your what you might want.
As soon as your activity becomes visible it will call OnStart() and as soon as it is ready for the interaction(such as touch ,click etc event). it calls onResume, at this stage your app is running and it is completely in foreground. When your activity start another activity or a dialog box then it calls onPause it means activity is visible but user can not interact with the Activity UI. in case we start another Activity which completely hides the previous activity then its onStop method is called
onPause: Called when another activity comes into the foreground.
onStop: Called when that other activity is completely visible.
onResume: Called when your activity is navigated back to from the onPause state.
Maybe your app was already in the onStop state, so then it would call onRestart.
I often see examples of classes which end with finish(), but definitely not always. My question is when should you end a class with finish()? And what does it do exactly, what is the difference between ending a class with the back button and ending it with finish()?
Thanks in advance!
finish() can be called to kill (destroy) an Activity instance. If you don't need to close your Activity manual, which is true in many cases, you don't need to call this method.
But if you require a button somewhere in your activity that says "close", then you should use this method. But in general the back button behavior in Android will handle things like this.
The back button does not actually finish your activity, finish() calls the onDestory() method right away, while the back button does not.
When the back button is pressed, the onStop() method is called, but the onDestory() method call might be delayed by the system, this so that the Activity can be resumed by the system which is cheaper (in resources) than a full restart.
Lifecycle:
http://developer.android.com/reference/android/app/Activity.html#ActivityLifecycle
Finish():
http://developer.android.com/reference/android/app/Activity.html#finish()
You finish Activity class with finish() method when you need to end the Activity immediatly at specific point. If you press back button, you will go through the lifecycle (onPause(), onStop() then onDestroy()) automatically.
One reason to use finish is when you have started the activity with
void android.app.Activity.startActivityForResult(Intent intent, int requestCode)
In this case you dont go back to the Activity which started it with another startActivity but with finish
Back button takes you to the last activity in the stack whereas finish() destroys the current activity. You can call finish() on an activity for which you don't want the user return to. Example: LoginActivity
public void finish ()
Call this when your activity is done and should be
closed. The ActivityResult is propagated back to whoever launched you
via onActivityResult().
finish() is called to kill your activity instance after you did what you have to do with the activity. After that, you have no use with the activity. So simply call finish() and it will kill your activity.
If you press back button, it will call finish() automatically to kill the activity. It will go through the activity lifecycle(onPause(), onStop() and finally onDestroy())
The one reason with calling finish() is that, if you don't call it, when you navigate through activities, all the activities will be added to the backstack. So when you go back, you have to come back through these activities. So for e.g when you click back button, it simply kills the activity and it will be removed from the backstack.
I have a main activity and a sub activity.
The main activity starts the sub activity using startActivity, and passes an object in the intent.
The sub activity reads the object out of the intent in its onCreate action.
The sub activity updates the object, then returns to the main activity using startActivity, again passing the updated object back.
However, the main activities onCreate function is not called, so the code it contains to read the passed object does not run.
Further investigation indicated that the main activity onPause event is firing, i.e. it is only paused when the sub activity runs, so when the sub activity starts the main activity again, it just onResumes.
Does anyone know if there would be any disadvantages if I moved my data restore/store activities to the onResume and onPause events?
I'm not using the onCreate savedInstanceState, should I be?
How else do you pass a set of data items between Activities without using a database or those preferences? Should I be using a database? I have about 20 fairly individual data items.
Any help would be much appreciated,
Frink
I would check out the startActivityForResult() method rather than just startActivity()
That should give you a means to pass things back to the calling activity.
From http://developer.android.com/reference/android/app/Activity.html:
Sometimes you want to get a result back from an activity when it ends. For example, you may start an activity that lets the user pick a person in a list of contacts; when it ends, it returns the person that was selected. To do this, you call the startActivityForResult(Intent, int) version with a second integer parameter identifying the call. The result will come back through your onActivityResult(int, int, Intent) method.
Have a look at the Activity life cycle here.
Also, consider starting your sub-activity using StartActivityForResult.
It is more likely calling onResume() or onStart() depending on the child activity and how much control it takes.
Look at this page about 3/4's down at the graph.
http://developer.android.com/guide/topics/fundamentals.html
The parent never gets destroyed so it wouldn't have to recreate it. It should just get paused. You can override onResume() and onStart() just as you would onCreate().
Edit: Is there anything given to the user in the subactivity? It sounds like you don't actually need an activity you just need a java class that you can call methods on.
Why don't you call startActivityForResult from the main activity and get the data back in onActivityResult ? This is the normal way to do it.