Stop an app by calling the lifecycle callbacks - android

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.

Related

My activity invokes onCreate() before onResume()

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.

detect difference between pausing or leaving an activity vs switching activities?

I have an application with multiple activities and have some behavior in onPause on my MainActivity that I don't want to happen when switching to another activity.
Right now whenever I switch activities the MainActivity onPause() is called and it always runs the behavior.
Activity lifecycles are tightly coordinated, so when launching one Activity B, from Activity A, the following lifecycle events will take place: ActivityA.onPause, ActivityB.onCreate, ActivityB.onStart, ActivityB.onResume, ActivityA.onStop. You can definitely leverage this lifecycle coordination to achieve what you want, if you are move you "behavoir" to the lifecycle method onStop (which is a better place to do most shutdown/stopping work at).
Create a Lifecycle registrar object that will perform the "behavior" when there are no activities are registered in the Lifecycle registrar object. Register your Activities inside of their onStart() and onStop() liefycle callbacks. Inside of the deregister method of your Lifecycle registration object check to see if there are any registered objects and if their aren't you perform you "behavior" whatever that may be. You can extend this functionality to work with Services, just register and deregister the service with the Lifecycle registrar inside the Service's onCreate, onDestroy respectively.
Using onStop instead of onPause, has the added benefit of keeping you from doing your paused/stopped "behavior" when the app is actually in the background and not just partially visibly, such as the case when the system displays a dialog. For example, when requesting to start Bluetooth, the Android OS will generate a dialog prompting the user, and calling onPause. This makes since for some apps but not all apps, and when you think about it, there are a various other use-cases that will cause the app to enter onPause(), that would be annoying to the user for you app to perform shutdown processes.
I have personally utilized this scheme to maintain a open connection, while the app is open and close the connection when the app is killed, or placed in the background. I even modified the Lifecycle Registrar object to maintain the connection during device rotation.
Here's a solution (a little dirty), you can use a boolean to know when you're switching the activity, set it to true just before you call startActivity(intent), and set it to false in onResume().
P.S, using onStop() is better than onPause() in your case, i believe you don't want to delete those cookies when the activity is partially visible

Activity can do without onStart() particularly and onStop() as well?

This is a text I have copied and pasted from this training tutorial.
"Because the system retains your Activity instance in system memory when it is stopped, it's possible that you don't need to implement the onStop() and onRestart() (or even onStart() methods at all. For most activities that are relatively simple, the activity will stop and restart just fine and you might only need to use onPause() to pause ongoing actions and disconnect from system resources."
I don't understand it. Because to the best of my knowledge, an activity is only stopped by calling onStop() and is only started by calling onStart(). How can an activity start at all without an onStart method.
Do you people understand what they mean in this paragraph?
I think they are confusing you with the word "stop" which appears to have multiple meanings in the paragraph.
I would rephrase it as
Because the system retains your Activity instance in system memory
when it is not in the foreground, it's possible that you don't need
to implement the onStop() and onRestart() (or even onStart() methods
at all. For most activities that are relatively simple, the activity
will suspend and restart just fine and you might only need to use
onPause() to pause ongoing actions and disconnect from system
resources.
The point being is that the App can appear to be stopped, when in actual fact, the system has simply paused it and hidden it from the screen. When the user launches it again, the App doesn't need to start (because it technically hasn't stopped), so it is simply resumed.
When you make an Activity and extend the base class Activity, there is already code in the onStop(), onStart(), and onRestart() methods in the base class.
Your activity simply extends these methods, meaning that you could add more code to them by Overriding them.
So, even though Activities are only started and stopped through those methods, you do not have to explicitly override them in your application. In most cases you won't even have to worry about them: They will be called by the base class from which you are extending.
Please make sure, An Activity starts from onCreate method , then onStart is called by system. If you override onStart method then your overridden method will be also called after onCreate method. If you don't override , then default version of onStart is called.
onStop is called after onPause.
Please check this link , and take a look at Activity life cycle . Your concept will be clear.
Difference between onCreate() and onStart()?
you can use an Activity just fine without - if you need to do something special in onPause() you can override the method:
#Override
public void onPause(){
super.onPause();
// Your magic here!
}
Same goes for onStart(), onStop() etc. You don't need to override the methods but you can if you need to do something specific.

Android Application Suspend Resume

My android application has multiple Activities. I need to perform a few things when the Application resumes (Application not Activity).
Android application provides onCreate callback but no onResume callback.
Is there any way I can identify that my application has resumed?
Applications do not get paused or resumed, only individual activities do. You can think of the Application class as of a static object that gets created before any of your activities (that's why it has a onCreate() function) and gets destroyed when the system kills the process (no onDestroy() involved here).
I believe the only way you can do that is through the Activity. If you're looking to call something across all your Activities in the onResume you can probably use a static singleton as is suggested in the Application docs:
There is normally no need to subclass
Application. In most situation, static
singletons can provide the same
functionality in a more modular way.
If your singleton needs a global
context (for example to register
broadcast receivers), the function to
retrieve it can be given a Context
which internally uses
Context.getApplicationContext() when
first constructing the singleton.
Activities do have onResume() see here: http://developer.android.com/reference/android/app/Activity.html#ActivityLifecycle
#Override
protected void onResume() {
// ...
}
So when your application resumes - one of your activities will resume - handle it in each activity.
Use ProcessLifecycleOwner ProcessLifecycleOwner .
It will dispatch Lifecycle.Event.ON_START, Lifecycle.Event.ON_RESUME events, as a first activity moves through these events.
And Lifecycle.Event.ON_PAUSE, Lifecycle.Event.ON_STOP, events will be dispatched with a delay after a last activity passed through them

Stopping and starting a Service based on application state

I have a Service which tracks the location of the user. Currently, the Service boots when the application starts and stops when the application terminates. Unfortunately, if users keep the application in the background, the Service never stops and drains battery.
I would like the Service to stop when my application is not in the foreground. I was hoping the Application class would let me Override onPause and onResume handlers, but it does not have them. Is there another way I can accomplish this?
I haven't tested this yet, but it looks like if you use Context#bindService() (instead of Context#startService()), the service should stop when no more activities are bound to it. (see Service lifecycle).
Then use onPause()/onResume() in each activity to bind/unbind from the service.
Alternatively, you could add a pair of methods on your service which tell it to start/stop listening for location updates and call it from each activity's onResume()/onPause(). The service would still be running, but the location updates wouldn't be draining the battery.
Reading all the above answers I would suggest Simply add a boolean global flag for each activity & put it in your onResume & onPause & also while launching an Activity Something like this
public void onPause()
{
super.onPause();
activity1IsResumed = true;
}
&same for onResume
& similarly when launching a new Activity
startActivityForResult(myintent ,0);
activity2IsResumed = true;
activity1IsResumed = false;
then in your Service simply check
if(activity1IsResumed || activity2IsResumed || activity3IsResumed)
{
//your logic
}
else
{
//another logic
//or dont run location tracker
}
& you are done!
You should override the onPause and onResume methods on your Activity. If you have multiple activities you may want to have a common base class for them and put the start/stop logic into the base class.
I have not tried this approach but I think you can override the home key of android device by using KeyEvent.KEYCODE_HOME and you can use stopService(Intent) to stop your service and when again application resumes, you can write startService(Intent) in the onResume() method of your Activity.
This way I think your service will only stop when user explicitly presses home button to take application in the background and not when he switches from one activity to another.
What I would suggest is overriding the onPause/onReume methods as others have said. Without knowing more about the flow of your application and interactions between Activities, I can't give much more information beyond guesswork.
If your Activities are persistent, however, my recommendation would be to utilize the Intents better when switching between Activities.
For instance, each Activity should have a boolean "transition" flag. So, when you move from one Activity to the next, you set up an Intent extra:
intent.putExtra("transition",true);
Followed in the receiving Activity by: (in onCreate)
intent.getBooleanExtra("transition",false);
This way, for each Activity that launches, you can know whether it has come from another Activity, or if it has been launched from a home screen launcher. Thus, if it gets a true transition, then onPause should NOT stop the service--that means you will be returning to the previous Activity after it returns. If it receives no "transition" extra, or a false transition, then you can safely assume there is no Activity underneath it waiting to take over for the current one.
On the first Activity, you will simply need to stop the service if you are switching to another Activity, which you should be able to figure out programmatically if one Activity is started from another.
It sounds like the real problem is how to only stop the service when you go to an activity that isn't one of your own? One way would be to in your onPause method to stop the activity. Do this for all your activities. Then override your startActivity method. And in here do a conditional test to confirm that you are purposefully navigating to one of your own. If your are set a flag to true.
Now go back to your on pause overridden method. And only stop your service if the flag is not equal to true. Set the flag to false.
All events that navigate away will close your service. Navigating to your own will leave it intact.
Do the overriding in a base class that all your activities extend.
Writeen in my andolroid. Will post ezaple later.
Try using the Bound Services technique to accomplish this.
Bound Services | Android Developers
You can use bound services in a way such that the service will stop when no activities are bound to it. This way, when the app is not in the foreground, the service will not be running. When the user brings the app back to the foreground, the Activity will bind to the service and the service will resume.
Create methods registerActivity() and unRegisterActivity() in your Application object and implement first method in all you acts onResume() and second in acts onPause().
First method add activity to List<Activity> instance in your app object, unRegisterActivity() checks size of list in every call if==0 stopService();.

Categories

Resources