There is a function in my android app that needs to run every time the user tries to edit his or her profile. There are two parts of edit profile in my app (please don't ask why, it has a very long tedious reason behind it). I need to revert back the changes the user did in the first part of the edit profile if the user decides to cancel everything. I have made a cancel button in the part two of edit profile but my question is, what if user presses the return button or the home button on the device and the app calls the onPause() and on onStop()? how can I run the same code in these two phases of the activities? Anyone out there who knows how to put code in different states on activities? Do I just make a function onPause() and stick the code in there? Would that work?
Yes, it should definitely work. In your case, you should write your code in onPause() method.
Here is a summary of the Activity Lifecycle:
onCreate():
Called when the activity is first created. This is where you should do all of your normal static set up: create views, bind data to lists, etc. This method also provides you with a Bundle containing the activity's previously frozen state, if there was one.
Always followed by onStart().
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//Write your code here
}
onStart():
Called when the activity is becoming visible to the user.
Followed by onResume() if the activity comes to the foreground, or onStop() if it becomes hidden.
#Override
public void onStart() {
super.onStart();
//Write your code here
}
onResume():
Called when the activity will start interacting with the user. At this point your activity is at the top of the activity stack, with user input going to it.
Always followed by onPause().
#Override
public void onResume() {
super.onResume();
//Write your code here
}
onPause():
Called when the system is about to start resuming a previous activity. This is typically used to commit unsaved changes to persistent data, stop animations and other things that may be consuming CPU, etc. Implementations of this method must be very quick because the next activity will not be resumed until this method returns.
Followed by either onResume() if the activity returns back to the front, or onStop() if it becomes invisible to the user.
#Override
public void onPause() {
super.onPause();
//Write your code here
}
onStop():
Called when the activity is no longer visible to the user, because another activity has been resumed and is covering this one. This may happen either because a new activity is being started, an existing one is being brought in front of this one, or this one is being destroyed.
Followed by either onRestart() if this activity is coming back to interact with the user, or onDestroy() if this activity is going away.
#Override
public void onStop() {
super.onStop();
//Write your code here
}
onDestroy():
The final call you receive before your activity is destroyed. This can happen either because the activity is finishing (someone called finish() on it, or because the system is temporarily destroying this instance of the activity to save space. You can distinguish between these two scenarios with the isFinishing() method.
#Override
public void onDestroy() {
super.onDestroy();
//Write your code here
}
You can do many things inside both onPause and onStop, just remember to call super.onPause();, super.onStop(); or whatever you need inside each one, just follow the pattern below. Simply add the code to your Activity and you're good to go.
#Override
public void onPause() {
super.onPause(); // Always call the superclass method first
// Do what you want.
}
Additionaly, if you want your users to be able to go back on your activity and edit something instead of closing it, you can just call onBackPressed():
#Override
public void onBackPressed() {
super.onBackPressed();
// You can just call onStop to close the app
// or do what you want.
}
Only onPause is guaranteed to be called
Related
I want to do a certain thing in my activity's fragment's onresume, but only if Back button has been pressed, and not if the app has been hidden behind another activity or "minimized" using "home" button/
How can I do that
onPause() will be called when the Activity is moved to the background. onPause() is where you deal with the user leaving your activity. See the diagram here.
If another Activity comes in onPause() is called. You can override onPause(). You can do anything/save anything there. When the activity again comes into foreground onResume() is called. You can override that also, and restore anything there.
#Override
public void onPause() {
super.onPause(); // Always call the superclass method first
// Release the Camera because we don't need it when paused
// and other activities might need to use it.
if (mCamera != null) {
mCamera.release()
mCamera = null;
}
}
#Override
public void onResume() {
super.onResume(); // Always call the superclass method first
// Get the Camera instance as the activity achieves full user focus
if (mCamera == null) {
initializeCamera(); // Local method to handle camera init
}
}
For Back Button see this.
The onBackPressed method is available from your Activity. Passing this to your Fragment could be done through a Broadcast, or possibly an Event bus (I'd recommend Otto for this). That way, your Activity can notify your Fragment of the onBackPressed call.
You can do it easily: just use a variable in your sharedPreference and toggle it in onBackPressed in your activity to separate it from other actions that may cause onPause, then in onResume reset it :)
In my Activity, I have overrode onDestory() and just put a log call to show if this method is being called. (tested on Android 4.2.2 and 4.4.4)
#Override
protected void onDestroy() {
Log.i(TAG, "onDestroy() was called");
super.onDestroy();
}
When I press the back button, this method gets called (I saw the log).
I believe this should not happen unless phone gets low in memory or something. I have nothing much in the app but the MainActivity and some fragments.
Here is the log when the user is in the MainActivity and presses the back button:
I/MainActivity? onBackPressed() was called
I/MainActivity? onStop() was called
I/MainActivity? onDestroy() was called
Why this happens?
I also checked for isFinishing() in the onPause() and it always returns true
From the Javadoc :
Perform any final cleanup before an activity is destroyed. This can
happen either because the activity is finishing (someone called finish
on it, or because the system is temporarily destroying this instance
of the activity to save space. You can distinguish between these two
scenarios with the isFinishing method. Note: do not count on this
method being called as a place for saving data!
When you press back button inside an Activity, it will call finish(), which will "close" it.
Activity.java
/**
* Called when the activity has detected the user's press of the back
* key. The default implementation simply finishes the current activity,
* but you can override this to do whatever you want.
*/
public void onBackPressed() {
if (!mFragments.popBackStackImmediate()) {
finish();
}
}
When it happens, onDestroy() can (and usually will) be called.
protected void onDestroy ()
Perform any final cleanup before an activity is destroyed. This can happen either because the activity is finishing (someone called finish() on it, or because the system is temporarily destroying this instance of the activity to save space. You can distinguish between these two scenarios with the isFinishing() method.
The same reason also goes to why putting isFinishing() inside onPause() always returns true, if you press the back button (call finish()). It will not return true if you hide the Activity with other method, e.g. pressing the home button.
I have 3 pages in my application. Page A,B,C. When i click next button in A page the page will navigate to B page. In that page there will be some request and response process and Progress indicator will happen. Then when i click next the page will navigate to C page. There also some request and response process and Progress indicator process will happen. Now my problem is when i click back button from page C The page is navigate to B page. But the request response process and progress indicator process is working. Here i don't want do this process when i click back button. Now i have try like this:-
#Override
protected void onStart() {
super.onStart();
Log.v(this.getClass().toString(),"onStart");
}
Here the request and response process is not working when i click back button. But the progress indicator is loading. This progress indicator is continuously rolling. How to disable all the functions. I just want to go back. Do not do any other work. Please help me to solve this issue. Sorry For the poor English..
As you can see, you add a flag Intent.FLAG_ACTIVITY_CLEAR_TOP. This flag will clear all previous activities.
Intent.FLAG_ACTIVITY_CLEAR_TOP - If set, and the activity being launched is already running in the current task, then instead of launching a new instance of that activity, all of the other activities on top of it will be closed and this Intent will be delivered to the (now on top) old activity as a new Intent.
And also you finish the current activity, so navigating back to page B call B's onCreate method where you have those requests and process stuff. Avoid adding flag and finish() methods.
You don't want to override the onCreate() method for this usecase, why would you do that? The activity is created, and the process will run. What you want is to override the onBackPressed() method, so that you cannot exit the Activity until the process is complete.
Similarly to these: Android: Proper Way to use onBackPressed() with Toast but here you want to make a boolean that is set to false while the process is not complete, and set to true when it's done. Allow onBackPressed() to call super.onBackPressed() only when the boolean is true.
#Override
public void onBackPressed()
{
if(processesCompleted == true)
{
super.onBackPressed();
}
}
You can't disable the onCreate() method in android but you can however override it like you do with the onStart().
I suggest you take a look at the life cycles of either fragments or activities, depending on which you use.
Fragments:
http://developer.android.com/guide/components/fragments.html
Activities:
http://developer.android.com/reference/android/app/Activity.html
It is hard to understand what the problem really is without more code, but basically the code in onCreate will mostly not be called when you press the backbutton since an activity will be paused until the phone needs more resources and then destroys it. If an activity is destroyed the onCreate method will be called and there is nothing you can do to change that.
If my answer dosen't help, please provide more example code.
If all your cards have different activities, the backbutton should work perfectly. However if your activity is brought to the front, nothing will be reloaded, except the onresume. In the onresume you can perform a new loading structure or something you want to achieve.
When you don't have different activities, use the override at onBackPressed(), that will handle the backbutton.
But place some code for a better answer
You can create a new function in which you run the processes and call
it on onCreate and use a Boolean flag to make sure when you go back to
that activity and flag is checked the function is not called. Then
save the value of flag in savedPreference onPause() method and you are
done and onCreate() method load your saved preference.
Something like this
boolean flag = false;
#Override
public void onResume()
{
super.onResume();
// load savedPreferences
}
#Override
public void onPause()
{
super.onPause();
//save savedPreferences
}
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
if(flag == false)
{
//function call
processes();
}
}
private void processes()
{
flag = true;
// do stuff here
}
onCreate() does not get called when I leave the application using back button and start it immediately. I believe this is because, Android has not killed the application process yet. I tried using #AfterViews, the same happens. How could I make sure that every time the application is started, my specific code runs?
Does not get called when I leave the application using back button and then start.
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
methodToRun();
}
I use this onBackPressed() to exit the application.
#Override
public void onBackPressed() {
this.moveTaskToBack(true);
this.finish();
}
Even #AfterViews does not get called when I leave the application using back button and then start.
#AfterViews
void checkAgreementFlag(){
methodToRun();
}
I want methodToRun() to always get called. How would I do it?
Call methodToRun() from onResume() of activity.
onResume(): Called when the activity will start interacting with the user. At this point your activity is at the top of the activity stack, with user input going to it.
onCreate(): is called when your application is starting first time.
onRestart(): Called after your activity has been stopped, prior to it being started again.
onStart(): Called when the activity is becoming visible to the user.
onStop() : When the activity is no longer visible.
For the back key scenario activity lifecycle:
onCreate()->onStart()->onResume()->Activity running
After pressing back key
onPause()->onStop()
If the activity is coming back then
onRestart()->onStart()->onResume()->Activity running
otherwise onDestroy() will be called.
I was testing out this code which shows which state an activity is in
public class Activity101Activity extends Activity {
String tag = "Lifecycle";
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// setContentView(R.layout.main);
setContentView(R.layout.activity_activity101);
Log.d(tag , "In the onCreate() event");
}
public void onStart()
{
super.onStart();
Log.d(tag , "In the onStart() event");
}
public void onRestart()
{
super.onRestart();
Log.d(tag , "In the onRestart() event");
}
public void onResume()
{
super.onResume();
Log.d(tag , "In the onResume() event");
}
public void onPause()
{
super.onPause();
Log.d(tag , "In the onPause() event");
}
public void onStop()
{
super.onStop();
Log.d(tag , "In the onStop() event" );
}
public void onDestroy()
{
super.onDestroy();
Log.d(tag , "In the onDestroy() event");
}
}
so I see that onDestroy() is only called when we press the back button while the activity is on screen, and is never called otherwise. So it should be running in the back ground if I press the home button while the activity is running. However, if I go to Settings -> Apps -> Running I can't see it on the list. So does that mean it is running in the background or not?
Again, Again, this code shows that onPause() is always followed by onStop() and onStart() is always followed by onResume(). So why are they defined as different functions in the Android environment and not combined?
Here I give you biref idea of activity life cycle...
onCreate():
Called when the activity is first created. This is where you should do all of your normal static set up: create views, bind data to lists, etc. This method also provides you with a Bundle containing the activity's previously frozen state, if there was one. Always followed by onStart().
onRestart():
Called after your activity has been stopped, prior to it being started again. Always followed by onStart()
onStart():
Called when the activity is becoming visible to the user. Followed by onResume() if the activity comes to the foreground, or onStop() if it becomes hidden.
onResume():
Called when the activity will start interacting with the user. At this point your activity is at the top of the activity stack, with user input going to it. Always followed by onPause().
onPause ():
Called as part of the activity lifecycle when an activity is going into the background, but has not (yet) been killed. The counterpart to onResume(). When activity B is launched in front of activity A, this callback will be invoked on A. B will not be created until A's onPause() returns, so be sure to not do anything lengthy here.
onStop():
Called when you are no longer visible to the user. You will next receive either onRestart(), onDestroy(), or nothing, depending on later user activity.
Note that this method may never be called, in low memory situations where the system does not have enough memory to keep your activity's process running after its onPause() method is called.
onDestroy():
The final call you receive before your activity is destroyed. This can happen either because the activity is finishing (someone called finish() on it, or because the system is temporarily destroying this instance of the activity to save space. You can distinguish between these two scenarios with the isFinishing() method.
So..onStart method call when activity comes in the foreground without interaction of user...and onResume method call when user starts interaction...so the functions of all methods is different ..
And once you press home button or back button your app running in the background and once you kill it from task manager it will shows nothing in the settings...
Once the activity goes in backstack, it is in suspended mode. So you dont see it in running app list. Once you relaunch such suspended application, it comes to foreground from backstack and starts to run. It is kept in backstack to preserve its state and resume from the place where it got stopped before going in background.
To understand why, onStart is needed before onResume follow the link below. It will clear all your doubts very clearly:
Difference between onStart() and onResume()
onStart isn't always followed by onResume. onStart is called when you Activity is visible, and onResume is called when your Activity is active. For example, an Activity could be visible but not active if there was a dialog partially covering it.
Thats' because there's a chance that onStart might not get called even when onResume actually is, there's a scenario when the activity might go to onPause only, without going to onStop [it only happens when activity is partially visible, not completelly covered by another activity], hence when comming back to activity only onResume will be called and not onStart.
Same with onPause, its always executed before onStop but onStop might not be called after onPause, as mentioned before, it could be called without onStop being actually called. If you press HOME you will not see the behavior i just explained because the activity is not partially visible, in order to reproduce it you have to find a way to make another component come on top without completely covering the activity...
Hope this helps.
Regards!