I am new to Android, but after studying the Activity Lifecycle, I understood that if I minimise the app, it should call onPause(), and while I reopen it should call onResume(). But, in my case, it calls onCreate() first and then onResume(). This is causing my widgets and other variables to enter wrong state.
My app only has an activity.
Why is the onCreate() method being invoked before onResume()?
It is possible that the app process is killed by the system either from onPause() or onStop() to create room in memory for other apps in the foreground, in which case when you reopen the activity, it will be created. In that case onCreate() -> onStart() -> onResume() is the expected sequence. When the activity is no longer visible, onStop() will be called, so when you navigate back to the activity onStart() -> onResume() is what takes place.
More on activity lifecycle here.
Additionally, since Android 10 there are some restriction of apps running from background. And "an app running a foreground service is considered to be running in the background" which is what you are describing. That may be why it is destroyed and app lifecycle starts from onCreate()
If I understand the issue correctly, it sounds like you're receiving a new instance of your Activity when you're looking to resume it instead. You can change how Activities are handled by setting their launch mode.
To resume an Activity if it already exists you could change its launchMode value in your Manifest to something like this:
<activity
android:name=".MySingleInstanceActivity"
android:launchMode="singleTask" />
There are several launch modes available and there may be one that's better suited for your project. You can read more about tasks and launch modes at https://developer.android.com/guide/components/activities/tasks-and-back-stack#TaskLaunchModes.
Related
I want to use Application.ActivityLifecycleCallbacks to monitor how many activities are there in the back-stack. Can I increment/decrement counter in onCreate/onDestroy to handle this?
onDestroy is NOT guaranteed to be called every time an activity is destroyed.
If the user clicks back to destroy it, onDestroy will be called.
If the user swipes the application from the recent app menu, onDestroy will NOT be called.
If the application crashes, it's undetermined if it'll be called (from my experience, it isn't called).
Is onDestroy always called when android destroys activity to save memory?
Yes
Documentation:
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.
I want to use Application.ActivityLifecycleCallbacks to monitor how
many activities are there in the back-stack. Can I increment/decrement
counter in onCreate/onDestroy to handle this?
Better to counter in the onStart() and onStop() methods, onCreate() doesn't guarantee visibility. For example if somehow something stopped onStart() from happening.
onDestroy() is the final method that is called on an Activity instance before it’s destroyed and completely removed from memory. In extreme situations Android may kill the application process that is hosting the Activity, which will result in OnDestroy not being invoked. Apparently most of the Activities will not implement this method because most clean up and shut down has been done in the OnPause and OnStop methods.
For more details please visit Android Developers Portal.
(https://developer.android.com/reference/android/app/Activity.html "Android Developers")
well here's a weird one that's been making my eyes cross for a few hours.
please be patient, much of this is explanation.
i have an Activity. its launchMode is singleTop. i've got log statements in it so i can see which of the various lifecycle routines are being executed.
i start said Activity and it goes thru
onCreate()
onStart()
onResume()
the Activity is passed an Intent and the Intent is picked up by something that runs after onResume()
i think the following happen because my Activity gets pushed to the background because of an incoming cell phone call.
onPause() <---- since i HAVE NOT pressed Back indicating the activity is over this SAVES STATE
while i'm out of the app running my Activity, the OS needs more resources and that, i think, explains why this is called:
onStop()
then i navigate back to my app and i see this runs:
onNewIntent()
ok. i think i understand this - it runs because that's how the OS communicates with an Activity defined as singleTop after its already been started. am i right?
then i see
onRestart()
onStart()
onResume()
which is all standard stuff
then i hit Home, prior to running something that will consume a lot of resources and force the OS to kill my app
i see
onPause() <- saves state
onStop()
when i navigate back i see
onCreate()
onStart()
onResume()
which makes sense because my Activity was killed and i've navigated back. onCreate() is how you start something that wasn't already running (since it was killed). onStart() and on Resume() are part of the normal lifecycle.
so i hit HOME again, the OS kills my app
onPause() <- saves state
onStop()
and i go back to it
onCreate()
onStart()
onResume()
HERE'S WHERE THINGS GET ODD:
i'm done with my Activity and i hit Back to leave it
onPause() <------- i detect Back was pressed so i DO NOT save state and delete previously saved state
onCreate() <------- say what?
i expected to see the standard stuff that comes after onPause() like onStop() and onDestroy() but for some reason that doesn't happen.
the OS runs my onCreate() again but since the Activity is over and i tried leaving by hitting the Back key this was all detected in onPause() and NO STATE WAS SAVED.
onCreate() thinks its running all over again. but there is no Intent data and
since the Intent delivered in the first onCreate() is gone and i've deleted all saved state onCreate() quickly succumbs to a NullPointerException
what on earth is going on? more importantly, how do i make my Activity die and stay dead?
EDIT 1:
some new information just came to light.
in the problematic onPause()/onCreate() sequence i describe above i logged the value of isFinished(). it shows
onPause() - isFinishing() is true. good that is what i expect.
onCreate() - isFinishing() is false!?
so the OS really is truly staring my Activity again. but why?
I try to make Notification which must work only when Application UI isn't visible.
I tried to store preference which was written in onStart() and onStop() of my Activity. But sometimes, it's not working because another application became visible without MyActivity.onStop() being called.
What other method I can use for a Service to determine, if MyApplication is visible now? Or, maybe MyActivity?
If you already have code to keep track of the state of your app's UI, you can probably get it to work simply by putting the code in onPause() and onResume(), instead of onStart() and onStop().
It is possible for the UI not to be visible, or partially hidden, even before onStop() gets called ... as you found out.
Take a look at the Android Activity lifecycle diagram here:
http://developer.android.com/images/activity_lifecycle.png
and note the description:
The foreground lifetime of an activity happens between a call to
onResume() until a corresponding call to onPause(). During this time
the activity is in front of all other activities and interacting with
the user. An activity can frequently go between the resumed and paused
states -- for example when the device goes to sleep, when an activity
result is delivered, when a new intent is delivered -- so the code in
these methods should be fairly lightweight.
Read more about this in another question here.
How can I stop my whole App in simple terms? (all activities, services, Threads, etc. simply everything) The life-cycle callbacks (especially onStop() and onDestroy()) should be called.
Google suggests the following possible solution:
kill the process: but this wouldn't call the lifecycle callbacks
and finish(); but this is only for one Activity:
But is it possible to access this method from outside like:
//Getting all activityies, how?
//For each gotten activity
AcitvityName.finish();
or via or via getParent().finish(); ?
This did not help me: Best way to quit android app?
FD
#Override
public void onPause() {
if(isFinishing()){
//code to finish() all activitys threads etc.....
}
super.onPause();
}
in onPause() you can check for isFinishing() and then if it is finishing it goes to onDestroy() so you can execute some code youd like
Use a broadcast receiver to call all your activities and call finish locally in them, invoking the current lifecycle callbacks.
Broadcastreceiver and Paused activity
http://developer.android.com/reference/android/content/BroadcastReceiver.html
Android don't allows user close application directly. You may minimize it to background or directly killing process.
But if you want to call some callbacks and release any resources when user remove your application from screen - you may to do following:
Clearing activity stack in onDestroy method (or if you wish in onBackPressed, onHomePressed). It must calls onDestroy methods in all removing activities so you may release any extended resources in onDestroy method of activity which has links on it.
So when user exit from your application - it will remove his activities and release all resources.
Here is the scenario:
I have two Activities. Lets name them Activity A and Activity B.
Say Activity A is open. Now, when I go and open Activity B, Activity A is closed because the onStop() method is called.
Now, when I flip back to Activity A, the onCreate() method is called, but I want the onRestart() method called instead. How do I do this?
You cannot influence the livecycle of your app like that. There should be no reason to rely on onRestart(). If you use onStart() it will always be called no matter if the Android OS killed the app process in the background.
Check out this doc for further information:
http://developer.android.com/reference/android/app/Activity.html#ActivityLifecycle
Damn beat me to it but here goes anyway
According to the Activity Lifecycle onCreate() is called again if the Activity was removed from memory because the OS deemed that another app needed the memory. In this case, you can't ensure that onRestart() will always be called for your Activity.
Like already stated you must find a different way of achieving your goal by using the other Lifecycle methods such as onStart() or onResume
I'm not sure if it fits your needs, I had to do an update service that starts the first time I open ActivityA (main Activity) and stops when exiting from ActivityA (not returning back from ActivityB),
I've placed the "start code" in onCreate() when savedInstanceState is null and the "stop code" in onDestroy() if isFinishing() is true