Is there something in the Android developer guidelines that disuades developers from providing the option to "exit" (stop running) an application from within the application itself?
I love multitasking and all but it's not clear to me why:
the vast majority of apps don't have their own Exit functions and hence just keep running forever
don't give you a choice about running when you turn on the phone - they just do by default
Both of these things lead to memory usage constantly increasing and your device running with this performance burden all of the time despite the fact that you may only want certain apps to run some of the time.
Am I missing something?
Is there something in the Android
developer guidelines that disuadea
developers from providing the option
to "exit" (stop running) an
application from within the
application itself?
Yes. It is generally not needed, just as it is generally not needed to restart a Web server because some user with a browser decided (s)he is done with a Web app.
the vast majority of apps don't have
their own Exit functions and hence
just keep running forever
They don't keep running forever. Android will close things up as needed.
don't give you a choice about running
when you turn on the phone - they just
do by default
Those developers aren't paying attention to me.
Both of these things lead to memory
usage constantly increasing
Generally, it doesn't. If you find specific apps that do this, uninstall them.
and your device running with this
performance burden all of the time
Generally, it doesn't. If you find specific apps that do this, uninstall them.
Also, this question is a duplicate of this one.
"Both of these things lead to memory usage constantly increasing"
Which doesn't matter since Android apps are limited to a fixed amount of RAM. Freeing RAM won't give more RAM to other apps.
Essentially, there's no need for a quit button as long as the developer does a good job of designing their app. Android activities are stopped when they aren't visible and resources are needed elsewhere, so the are no longer consuming resources. You can read about the lifecycle here:
Here's a related question:
From Google's Android Application Fundamentals page:
Shutting down components
A content provider is active only while it's responding to a request from a ContentResolver. And a broadcast receiver is active only while it's responding to a broadcast message. So there's no need to explicitly shut down these components.
Activities, on the other hand, provide the user interface. They're in a long-running conversation with the user and may remain active, even when idle, as long as the conversation continues. Similarly, services may also remain running for a long time. So Android has methods to shut down activities and services in an orderly way:
An activity can be shut down by calling its finish() method. One activity can shut down another activity (one it started with startActivityForResult()) by calling finishActivity().
A service can be stopped by calling its stopSelf() method, or by calling Context.stopService().
Components might also be shut down by the system when they are no longer being used or when Android must reclaim memory for more active components. A later section, Component Lifecycles, discusses this possibility and its ramifications in more detail.
So it seems like Content Providers and Broadcast receivers should never be explicitly shut down, as they are inert while not handling their specific events.
As for Activities, I would argue in favor of having an end to it, but in certain cases. If your app has a finite state in which the user is done using it, why keep it alive until GC gets it? The activity manager still needs to keep track of that Activity while the user has finished their task. My best example for this is the Calculator. You open it, you have it solve a problem for you, and then you close it. If the onCreate function is so expensive that it's more effective to do onCreate once and then onRestart whenever the user moseys back to your application then you're probably doing something wrong. Maybe I'm misinterpreting how Android handles Activities, and if so I'm always interested in learning more :)
It all comes back to the answer that users want total control of their running and auto-start list and what they do and don't want installed, example: google maps, etc etc. there are no two ways about this.
Related
On Windows, MacOS and Linux, when an app is closed, the norm is that its process is also killed. This happens as default on Windows/ Linux, and on MacOS, it still seems like a good idea to press CMD+Q to kill the process when no app window is open.
On Android (and iOS too) when the app is backgrounded, its process still keeps living in the memory till the OS finds it necessary to push it out. The process can be killed but this step is not the default OS behaviour and is somewhat discouraged by the UX.
Why?
Update
Some of the replies do seem to suggest that there are potential benefits in keeping the app in memory. So a further follow up will be, why then main stream desktop OS(es) do not follow the same approach to reap all the same benefits?
Android is very good at managing its resources. It has a certain amount of memory (RAM) to work with, and it’ll happily allow apps to use as much as they need for best performance.
If RAM starts to get a bit short, and other apps and tasks need some, then the OS will quietly close one of the apps running in the background that you haven’t used for a while, and assign that app’s RAM to the new task.
As a result, apps can stay in memory for hours, days or potentially even weeks since you last used them. And this is fine. They’re not draining the battery or using other resources so there’s no downside; the upside is they will load much quicker when you need them, and load them right back to the place where you left off too.
(It’s also worth noting at this point that there’s really no benefit in keeping RAM free. RAM exists to be used, and using all of it at any given time—or virtually all of it at least—will ensure your phone or tablet runs smoother than if you try and keep some RAM free.)
With all this in mind, it becomes clear why closing apps can have a worse effect on Android than leaving them open.
Ref: androidtipsandhacks.com
Answering to your question update and agreeing with the already posted answers stating that keeping an app in memory may be better for battery and app resume/start up.
A mobile device is designed to be fully mobile, to be in your pocket or hand all the time, and connected to an electricity outlet just for charging, and usually nothing more. So, it must have a battery saving centric design.
A desktop is always connected to an outlet, so doesn't have the battery shortcomings and requirements of mobile devices.
About laptops, although they are portable, they are actually used most of the time also connected to an electricity outlet. The fact that they can be carried from one point to another doesn't make them comparable to mobile devices.
So, although desktop OS(s) now days have battery saving features tailored mostly for laptops, their design is focused with the fact that the host device will usually work connected to an electricity outlet, and they have never evolved to have a battery saving centric design, which is a "must have" requirement for mobile devices.
On the other hand, if you want to consider not the battery but the app resume/start up benefits, then actually such feature is already implemented in both types of OS(s), but in a very different way. For example in Windows you can minimize a program, this is the exact same thing as pressing the home button in Android. To close it you press the x button a the corner or the program's exit option, that would be like going to Android apps task manager (recent apps history) and killing the app.
Because some applications behavior relies on background services that can not work if the main process is killed. When you swipe off an application from the recents, you're not really killing the app, the background services are still there.
Imagine that you close Whatsapp and the OS thinks that it's a good idea to kill the entire process. You wouldn't recieve any message unless you re-launch the app.
According to documentation, there are 4 states of application process in android app.
Let's look at a few cases.
1. App has running Activity. User presses home button.
In this case app status will be moved from Foreground to Cached.
Cached state is used for providing better UX, when user switches between apps. Because opening a cached activity is much faster then restoring it from saved state.
2. App has running Activity and Service. User presses home button.
In this case app status will be moved from Foreground to Service.
Service state is used for processes which have some unimportant background job. In this case process is kept, because it has some background job to do. Of course you can move your Service to a separate process, but it is not a default behavior.
3. App has running Activity and foreground Service. User presses home button.
In this case app status will be moved from Foreground to Visible.
Visible state is used for processes, which are visible to user, but he doesn't interact with it directly. Foreground Service is used for doing important background job and keeps process at Visible state. Again UI and Background parts of app by default are placed in same process.
I am developing a simple app that just play a white noise sound in background while I am doing other things.
It works very well when I switch to other apps ( like games, chrome browser, etc ) but sometimes ( for example when there are many chrome tab opened ) the white noise sound stop and I need to reload my app.
I am NOT using Services, is this the reason ?
Because your apps is getting killed by the system to give up resources for to other apps (games, chrome, etc). So you need to use a Service.
Here an excerpt from Processes and Application Life Cycle
for more details explanation:
An unusual and fundamental feature of Android is that an application
process's lifetime is not directly controlled by the application
itself. Instead, it is determined by the system through a combination
of the parts of the application that the system knows are running, how
important these things are to the user, and how much overall memory is
available in the system.
...
A cached process is one that is not currently needed, so the system is free to kill it as desired when memory is needed elsewhere. In a
normally behaving system, these are the only processes involved in
memory management: a well running system will have multiple cached
processes always available (for more efficient switching between
applications) and regularly kill the oldest ones as needed. Only in
very critical (and undesirable) situations will the system get to a
point where all cached processes are killed and it must start killing
service processes. These processes often hold one or more Activity
instances that are not currently visible to the user (the onStop()
method has been called and returned). Provided they implement their
Activity life-cycle correctly (see Activity for more details), when
the system kills such processes it will not impact the user's
experience when returning to that app: it can restore the previously
saved state when the associated activity is recreated in a new
process.
I think Services is What You are looking For.
A Service is an application component that can perform long-running
operations in the background, and it does not provide a user
interface.
For better chance of preventing OS to kill your app, you should use a
Foreground Service
following the official guide here: https://developer.android.com/guide/components/services.html#Foreground
Remember that there is no way to be certain that OS will never kill your app, because when RAM becomes really low it could kill every process indipendently from type, following his priority rules
I made an android application with a runnable that checks something ever minute.
But the problem is the application goes [DEAD] after a couple hours without an error messages or anything.
Anybody have any idea what the problem could be?
That is not a problem, that is actually expected behaviour.
The lifecycle of all apps is managed by the Android OS. It decides whether to terminate an app in order to free resources and keep the system responsive. Apps that are currently is use have priority over paused and background ones. I think in your case the OS just decides to shut down the app because it thinks it's not needed anymore.
There are ways to get around this, but it all depends on what your app actually does. I don't know your implementation details, but may want to look into sticky Services or the JobScheduler in order to achieve what you want. Keep in mind that there is no such thing as a perpetually running background task that comes out of the box in Android (not should there be one) and usually implementations have certain limitations.
It could be the Android OS itself closing the app. If the OS requires more memory it will start to kill of other processes that have not been used for a long time (i.e. interacted with). You haven't stated how the check happens but it shouldn't be done directly within the app, but it sounds like it is something that a background service should be doing the work which would likely prevent this from happening.
You should NOT use Runnables for background processes, as they get suspended/killed by the OS as soon as your app goes off-screen.
If you want to let some processes run regularly, you have to stick with AlarmManager / BroadcastReceiver combination
I'm new to Android development. I'v developed an android application which needs to store the connection/data even after 1 hour. Currently I have all the data and the connections(chromecast mediaplayer) in a singleton class. But, when the user puts the app into the background for about an hour, the activity is destroyed so the connections,data etc are lost causing my app to crash when re-launched.
I've read up on the android services, Can I use these services to hold the singletons so even when the activities are destroyed I can have data binded back to the views when re-launched?
Or is there a way to make sure that the activities are not destroyed when android decides to do a cleanup?
Please advise
Thanks.
I think you might misunderstand what an Android application is.
Your application is a bunch of components that run in a single Linux process. Components come and go, within that process. You have absolutely no control over the lifecycle of the process itself.
The answer to part of your question is that "yes" a Service will stick around after an invisible activity is destroyed.
When an Activity becomes invisible, it gets destroyed. If your process is not doing anything else, then the process is likely to be killed too.
If your process is also running a Service, it is less likely that it will be killed. It is just less likely, though. The process will eventually get killed. When it does, your singletons will be gone. There is nothing you can do to prevent that. So the answer to the second part of your question is "no". You cannot depend on singletons in your service to be around when the process is relaunched
You might look into using the Application object. Its lifecycle is roughly the same as that of your process. It will not live forever but it will be around whenever any other component of your application is around (except ContentProviders).
It sounds like you want to keep connectivity to a chromecast device around when your application is in the background. Obviously services can be helpful but I have a few comments that may come handy:
Services can be killed by system but based on how you have set them up (e.g. the return value of onStartCommand()), they can be restarted by the system. When that happens, you cannot expect that your dynamic data is still there (for example your singleton). You need to include logic to recreate what you need again (for example, rebuild your singleton)
Phone can go to sleep when left for a little while (or user can lock his/her phone), so when phone goes to sleep, wifi may drop after a little while, based on the phone settings and the build on your phone; some do this more aggressively and some not (even if you hold a lock, it can still happen). The point is that you have to assume that it may happen. Even if you have a service, your Cast connection will go down due to wifi loss, so the proper way to handle things is not to try to keep the connection up all the time (since you can't) but is to have logic to re-establish connection when circumstances is right. In order to do that, you need to preserve enough information to be able to bring things to the state that they were. Your logic should also be intelligent enough not to reconnect if it shouldn't.
Android O.S can destroy any activity , when it is low at resources it destroys any activities to make more space for other apps.
But you can use background service to hold your singleton
You can use this link to create your background service
I currently have programmed a normal Andorid-App (no Service). It contains a timer for periodic checks. To avoid hassle with a service and communication between Service and App I ask myself whether there is a way to keep an App that is no longer in foreground alive.
Currently when I "close" the App, it is still alive until Android OS decides to kill it. Is there a way to avoid this kill - e.g. by a certain command in "onDestroy" or a certain App-flag?
My App is quite complex and I do not want to implement a Service as this -especially the communication/binding- increases the complexity. Is there an "easy way" or am I really forced to use Service+App? Maybe there is a trick to register the App for sth. special that has the side-effect that Android OS does not kill it when it is in the background.
Edit for better understanding: It is ok that the GUI can go into the background (vanish) when the user wants it, so my question is not how to let the GUI of my App permanently in the foreground. All I want is that the timer stays intact without the need for an additional Service.
Thank you all for ideas in advance!
Android is very unpredictable by the nature of the OS's killing selection and by the market fragmentation. I would not count 100% on anything being kept alive if it is crucial. However you can gamble and be pretty successful. This is what would help you:
Use very good "Best Practices" to keep your string pool and heap at a minimum as Android looks to kill memory hogs first off (and because you love what you do).
Add the persistent attribute to your application manifest tag.
To really help yourself out, run as a, or run a service because they are long running processes, are very light (if implemented well), and Android looks to kill these off lastly.
Give your service priority by running it as a foreground service.
Doing these things will increase the likely-hood that Android will not kill your application.
I don't think there is anything like that available. I suggest looking at AlarmManager for periodic tasks - this may mean you won't need to use a service.
The apps being available in the background is simply a caching measure by the android OS to avoid having to relaunch a frequenly used app from scratch. If you want to be able to count on your app running in the background, a Service is the correct solution. Its not the answer you are looking for, but I am not aware of any tricks to staying alive in the cache, and if there were any, I would not feel good about recommending them.