How does Android decide which app to kill? - android

I know that Android may kill applications e.g. if it's low on memory. In a comment to another question a user stated that if my app would require less memory, it would be less likely to be killed. I wonder: is this true? Where is such a behavior documented? Which other factors influence the likelihood of being killed?

is this true?
Perhaps.
Where is such a behavior documented?
It's not, which is why the answer to the previous question is "perhaps". The only way to determine the behavior would be to examine the Android source code, and that would only be relevant for Android devices built using that same source code. Not only can Google change the algorithm over time, but device manufacturers and ROM modders can change the algorithm as well.
Which other factors influence the likelihood of being killed?
The primary determinant is what is in the process, as is described in the documentation. So, a process with a running activity will be less likely to be terminated than a process with no running components at all.
Nothing else is formally documented. My understanding is that process age is a factor, so that apps with a service do not live forever, but I don't recall that this is mentioned in the docs.
Also, bear in mind that the user can get rid of your process whenever the user wants, via the recent-tasks list on 4.0+, or via a third-party task manager, or via Settings. Hence, you should make few assumptions about the longevity of your process.

Related

What is exactly "Adaptive battery", and what does it mean for app developers?

Background
Google has announced on Google IO 2018 something that's called "Adaptive battery":
https://youtu.be/ogfYd705cRs?t=3562
As a user, this sounds promising, but as a developer, this could be an issue in some cases.
The problem
They said it checks which apps are used more often using AI, and that the "OS adapts to your usage pattern" :
Adaptive Battery uses on-device machine learning to figure out which
apps you’ll use in the next few hours and which you won’t use until
later, if at all today
To me it sounds like it might be yet another step in the "war against background processing apps".
What I've found
Since this is very new, I haven't found anything of how it works, and if developers should be concerned about it and need to change apps.
Only things I've found are articles from user-point-of-view.
The questions
What is exactly "Adaptive battery"?
Should developers be worried when it's being enabled?
Which app components, background-processing classes, alarms, wakelocks, syncing classes, background/foreground services etc... - might be affected by it?
If indeed it can affect the nature of the app, is there any API to check if it's enabled, and act accordingly? If so, how?
How does it compare to other battery-saving mechanisms?
I agree, this “Adaptive Battery” sounds concerning. This new version of Android, named Android P, “puts AI at the core of the operating system and focuses on intelligent and simple experiences.” (1) On the developer’s blog, they quote, “For developers, Android P beta offers a range of ways to take advantage of these new smarts, especially when it comes to increasing engagement with your apps.” (1) It is pretty obvious that while they are trying to make their OS better for the general public, they have not forgotten their developers.
The two things that are the most concerning with Android P are the Adaptive Battery and Background Restrictions changes. I will try to answer your five questions to the best of my ability, but of course with Android P being in beta, not everything is ironed out yet.
1. What exactly is “Adaptive Battery?”
“In Android P we’ve partnered with DeepMind on a new feature we call Adaptive Battery that optimizes how apps use battery”(1). What Android is using DeepMind for is categorizing apps into different “App Standby buckets” which range from “active” to “rare.” Based on which standby bucket the application is put into, it will vary the restrictions on alarms, jobs, network and high-priority Firebase Cloud messages.
These buckets are: Active – meaning the app is currently being used. Working set – meaning the app is in regular use. Frequent – meaning the app is often used, but not every day. Rare – meaning the app is not frequently used. Obviously these buckets are not clear cut because they are dependent on the DeepMind AI that Android P is implementing. Please follow this link for a better explanation on what the buckets are and how they are used. Also, this link is the Appendix for Power management restrictions, that will also shed light on the Adaptive Battery.
They also say “If your app is optimized for Doze, App Standby, and Background Limits, Adaptive Battery should work well for you right out of the box. We recommend testing your app in each of the four buckets.”
2. Should developers be worried when it’s being enabled?
It looks like developers might have some cause for concern if they do not plan for this. Looking through the power management appendix I linked above, the biggest changes are how long jobs and alarms are deferred. However, it looks like if you force jobs or alarms, then they will fire.
I think, for developers, it would be wise to heed their warning of optimizing your application for Doze, App Standby and Background Limits. And if that is not the route you want to go, I would highly recommend at least make sure to test your app in each of the four buckets.
3. Which app components might be affected by it?
Because Android P is still in beta, these are subject to change. For now, the only app components that would be effected would be: Jobs, Alarms, Network, and Firebase Cloud Messaging. These are all effected differently based on the standby bucket that DeepMind decides they should be in.
Another note, I mentioned background restrictions and was going to elaborate a little on it here, because it is similar to Adaptive Battery in the sense of its limiting powers. Background Restrictions point out applications that have been using battery in the background, and allows users to put restrictions on them. “When an app is restricted, its background jobs, alarms, services, and network access are affected.” So if a user deems your application as taking too many resources, you will get restricted and it seems as if this is like being put into a low priority standby bucket. There are however, ways in the Android P API to check whether your app is restricted, which will be helpful towards developers.
4. If indeed it can affect the nature of the app, is there any API to check if it’s enabled, and act accordingly?
Yes, there are calls in the API that can tell you which bucket that you are in, and whether your app is being restricted as I said before. For example, you can find out what bucket that your application is currently in by calling: UsageStatsManager.getAppStandbyBucket()
Also, there are great ways to test your application using the Android Debug Bridge in each of these buckets. Just follow this link.
5. How does it compare to other battery-saving mechanisms?
This type of bucket battery saving way, to my knowledge, has never been implemented before. This is a new experience. However, I know that the background restrictions have been available since Android Oreo, where the users could see what apps were acting out. However, in Oreo the users could only see what apps were sucking battery, but couldn’t place restrictions.
An interesting example I found here: “So, for example, let’s say you really only look at Instagram at night. In that case, Adaptive Battery will learn this behavior and keep the app in sleep mode during the day, then wake it up when you’re most likely to use it.” That is an example they gave for Android P for how DeepMind will work to place applications into these standby buckets.
Overall, I do think that this is a good step for Android, who has always been plagued by battery issues. As long as developers are not spamming their users with wake locks, notifications, or other things that aren’t necessary, this really shouldn’t impact their application too much. However, this does make it so developers have to put in more work, like checking what bucket they are in and acting accordingly. Time will tell if this is a good step for Android.
Links
(1) - https://android-developers.googleblog.com/2018/05/whats-new-in-android-p-beta.html#androidbeta
(2) - https://developer.android.com/preview/features/power#buckets
(3) - https://developer.android.com/preview/features/power-details
(4) - https://www.howtogeek.com/352364/how-android-p-will-increase-battery-life/

Best way to determine the current foreground (running) application (using a service?)

I am building an application which needs to determine the time an app has been running, so I can show the user statistics of the apps he / she uses. I found multiple solutions online but al those have their flaws.
Here are the two best options I found:
Using a polling mechanism with a service. This solution seems battery inefficient and depends on a deprecated method (since API level 21):
getRunningTasks(int maximum)
Using the new "App usage statistics" introduces in Lollipop, but this solution will only work with devices running android > 5.0. But I want to support older devices as well.
I have also searched for a intent firing when a app starts or stops but there seems to be none (see Summary). This post confirms that. Also I found a class: ActivityLifecycleCallbacks which gets callbacks when a activity changes it state. But this is only for internal (read inside your own application) use.
So my idea is to use a service to poll the current foreground app on devices which are running version other than lollipop and use the new API on devices running lollipop or greater. But is this "service" idea the best option because as I said before it seems battery inefficient? Maybe there are better options?
Faas
1st option is definitely bad as it is deprecated.
I would rather suggest you to use android.app.usage
What the app you cite is probably doing is wasting a lot of CPU time, RAM, and battery life, polling ActivityManager continuously.
Bear in mind that what you propose to track, if you plan on having anyone other than the user access it, borders on privacy violations of the type that got CarrierIQ in a fair amount of trouble.

How to detect programmatically when other apps are closed / force stopped

I am developing an android application in which i need to perform an action when other apps are closed / force stopped. This detection has to be made from a service which is been running in the background once started. Making the service to run continuously is not a problem but making detection when other apps are closed is the problem. Please do anyone have any solution.....
I don't believe it's possible to detect when an app is force stopped. Even the app being stopped doesn't get that information. You can detect if an app is currently closed by using the BroadcastReceiver. Here's a pretty decent tutorial on using that: http://saigeethamn.blogspot.com/2009/10/android-developer-tutorial-part-11.html
I am not aware of any official way in which Android allows apps to listen in on when other apps are forced to close. So you’d have to poke around under the hood.
Disclaimer: Doing so is unsupported. While just reading information is unlikely to cause any harm, there’s no guarantee that it will work universally. If you get it to work on your particular build of Android, may still fail on different builds. Also, Google keeps locking down features in Android with every new version, so there’s a high likelihood a future update may break things.
I haven’t actually tried any of the below, hence there is a possibility they will fail to produce the expected result.
That being said, here are a few things you can try. You may need to combine them to get something useful out of them.
Processes
Since Android is based on a (somewhat) modified Linux kernel, it generally supports most Unix mechanisms for working with processes.
Apps are launched by a process called zygote. A quick run of ps on an Android device shows me that all user apps (as well as the higher-level system apps) seem to be children of the zygote process. Thus you could get a list of all processes, find the PID for zygote and grab all its child processes.
Then you might be able to waitpid() on each process and examine its exit status. You may want to experiment around with this a bit and see if the exit codes tell you anything about how the process ended.
Also take a look at ptrace(). You might be able to monitor zygote directly with an option such as PTRACE_O_TRACEFORK, which should basically notify you each time a new app is launched, allowing you to monitor its PID as well.
Downside: You probably need to be root to do any of this. Linux doesn’t let users see other users’ processes (which is an essential security feature), and Android harnesses (or abuses) the user model by running each app with a separate Linux UID.
Logcat
Looking at various logcat apps (e.g. aLogcat), you might be able to monitor the logcat for events like this:
12-26 10:01:27.670 I/ActivityManager( 774): Process org.openbmap (pid 21647) has died.
There are a few events that may occur when an app crashes—ActivityManager will tell you when an app has died, or you might watch for unhandled exceptions.
Note: While this doesn’t seem to require root (aLogcat works fine without), it may not work under all conditions. I have seen devices where aLogcat sees next to no entries, though I didn't investigate why. In those cases, the above approach would not work as it depends on being able to read the logcat.

why does the android os need to have apps running in the backround that are not ever selected

why cant android os be more like apple os on the the ituch/iphone? where the app doesn't run until it is selected. it is also closed; stays closed until it is opened again.
i think this would make the android phones run faster and more efficiently(battery would last longer).
A lot of Android apps (I think most of them) run exactly as you describe it - they have an activity that is closed or suspended as soon as you leave it - a suspended Activity only consumes memory and can be discarded in an instant. (iOS does nearly the same)
Even on the iPhone there are applications that run in the background, the most prominent example being Mobile Safari. The difference is that only Apple can write applications that run in the background without restriction, and that a regular user has no way of monitoring these background apps. (this has led to massive overcharging issues in the case of users leaving Mobile Safari on a page where streaming content was loaded.)
There are legitimate use cases where you need an app to continue running in the background (downloading, uploading, playing music, waiting for a VoIP call) - none of it was possible for a third-party to do it on the iPhone until iOS4, making applications such as Pandora or Skype nearly useless.
For good or ill, Apple consistently restricts what third-party developers are allowed to do on iOS devices (App Store policy, private APIs, specialized APIs for background tasks mentioned in point 3). On the other hand, Google seems to prefer that third-party Android developers have access to the same APIs as Google's Android app developers.
The biggest Android performance problem IMO is responsiveness, the fixing of which is a lot more involved than saying "no Apps in Background thx". (See http://android-developers.blogspot.com/2010/12/new-gingerbread-api-strictmode.html for more information)
An Android developer's blog explains the reasoning behind Android multitasking.
We did not want to require that users close applications when "done" with them.
Mobile devices … have fairly hard limits on memory use.
These competing constraints were a key motivation for Android's design.
The fact that you can see an application's process "running" does not mean the application is running or doing anything.
The articles linked from there also have interesting things to say on the subject
The RadioActive Yak:
When should your app include an exit button? The Short Answer: Never.
Wickenden:
One of the first things the naive but technically inquisitive new android user does is begin to wonder how all the things they are running should be “shut down”.
Google’s android system has been designed for multi-tasking in ways that allow programs to be ready to respond to a changed environmental condition instantly (an alarm to wake you, a notification that you have arrived at your destination and so forth) as well as actually “running” and consuming resources when needed. Additionally the android system itself is smart about how it deals with low memory conditions and is capable of completely blowing away applications in such a way that their state is remembered and can be restored when there is more memory.
Task Killers (whose behavior is radically clipped in Android 2.2 “Froyo”) actually can cause harm by destroying a process that other apps need to function correctly.

Samsung "App optimisation" feature kills background applications after 3 days

We are currently developing an Android app that is a fitness-tracker application. It runs constantly in the background, and it works fine on most devices, but we've been having issues with the application dying completely on some Samsung devices. After some investigation, it seems like some Samsung devices has a completely custom "App Optimisation" feature (http://forums.androidcentral.com/samsung-galaxy-s6/599408-app-optimisation-after-updating.html), which is basically a (very) primitive version of the Doze feature that exists in later versions of Android which basically just murders apps if they haven't been used for three days.
As this app is more or less only doing logging, and doesn't open the activity, it presents a big problem for us, because this feature is pre-enabled on many Samsung devices. The problem is solved by using a foreground service, but that is a sledgehammer of a solution that requires disturbing the user with a constant notification, and we really don't need the app to be in the foreground - we are fine with the normal power management of Android.
The Samsung App Optimisation feature clearly states that it will "optimise" apps if they have not been used for three days. Does anyone have insight in what Samsung considers to be "used" and can I somehow trigger that?
Side-rant: In my opinion, this is a badly implemented feature that makes development on Android more hostile. Besides our use case, it will any messenger applications break. If it were not for the fact that Facebook Messenger and Whatsapp are hard-wired to be exempt for the app, users would be going crazy because it would be breaking their experiences.
I've owned (and currently own) Samsung devices, so I know a little as to how it works from the user's point of view. The technical specifications and how it works on the inside is an entirely separate issue, and one I can't answer.
The system can detect if you open an app. Samsung uses that in their app optimization, and will save power on apps that haven't been used in over three days. It is a terrible system though.
It ignores background-processes that may be critical to apps, and even if it is an app you actively use, like a fitness tracker, it will have issues. To quote what it says inside the app optimization-list:
"To save battery power, apps that haven't been used for more than 3 days will be designated to save power. Apps designated to save power may not show notifications"
(Rough translation from Norwegian, originally taken from an S6 running Android 6)
Therefore, apps that have been manually, or automatically set (3 days of no use) may give various issues with background processes. But remember that the user can set any app to never save battery, and ignoring the automatic setting. So with this in mind, let's consider possible solutions.
There is one scenario where you do not need to worry about the app and app optimization: When app optimization is disabled entirely.
Looking aside that, there is really only two things you can do:
Ask users on Samsung to disable battery optimization for your app to prevent issues
As #MinaSamy suggested (in their now deleted answer), SyncAdapter and having a periodic synchronization. Note that I haven't tested this, so I don't know whether it works or not.
And there's also a third option, which really isn't a solution, but you can ignore it and gamble on app optimization being disabled, or just not care about it at all.
Does anyone have insight in what Samsung considers to be "used" and can I somehow trigger that?
As far as I know, unless Samsung added some safeguards against accidental opening or added some kind of minimum activity requirement, opening is enough. It appears to be a "stupid" feature, which runs on hard-coded rules rather than a dynamic system that actually detects app use and sets power saving relative to that. It's "easy to enable", but fortunately easy to disable as well.
Meaning you cannot trigger an event that will keep it alive (unless SyncAdapter does the trick)
And to make the facts clear, from #Neil's answer:
It does seem like the user can do this, so there must be some database or setting somewhere that controls it.
There kinda is. There are a total of four settings, three of which are app-specific, and it is stored in a database (or some other form of data storage). These four settings can be used, although extremely shallow, to alter the behavior of the app optimization:
Always optimize
Automatic optimization
Never optimize
Disable app optimization
The first three options are on a per-app basis, which means each app can have separate settings. Disabling app optimization is exactly what you'd expect: it disables the entire feature for all apps. If it's disabled entirely, nothing is optimized.
There's also a website listing ways of bypassing optimizations on a per-brand basis. The entry for Samsung is more or less what I've said: tell the user to manually disable optimization. There are no developer solutions.
In settings>device health>battery there's an option to "put unused apps to sleep". You can turn it off, or change the amount of time it takes, which is 3 days by default.
Sounds like that's your problem.
https://forums.androidcentral.com/samsung-galaxy-s10-s10-plus/964083-whats-disabling-some-my-apps-background.html
Is there a reason you can't add your service to the 'don't optimise' list?
It does seem like the user can do this, so there must be some database or setting somewhere that controls it.
Alternatively, if you detect you are installing on one of the devices, open the optimise activity page, and show a message saying "Don't optimise us!".
As a workaround, i implemented the SyncAdapter mechanism, using this link as a good starting point: https://github.com/bmeike/MiniSync
It doesn't work perfectly (for testing, in my app i write a log every 1h, and after 3 days, it starts not respecting this scheduling), but at least it doesn't stop after 3 days, without the need to put the app in ignored optimization mode.
UPDATE: After the update to android PIE, scheduling stopped again after 3 days.
On another device, same app with android Oreo, scheduling is working (even if not completely respected).
On Samsung phones, the culprit is this Sleep setting:
You have got to take your users to this system settings screen and ask them to turn the feature off.
In my opinion you should implement a 'Broadcast Receiver' that listens to a custom 'Intent' and this 'Intent' to be Broadcasted by the 'Service' from 'onDestroy()' method of the 'Service' because when the 'System' kill the 'Service' this method will be called definitely.
And when the 'Broadcast Receiver' receives the 'Intent' you should start the 'Service' again.
And to distinguish between you stopping the 'Service' or the 'System' stopping the 'Service' just use some 'booleans' stored in 'SharedPreferences' and then in the 'Broadcast Receiver' you decide whether to activate the 'Service' or not
we are fine with the normal power management of Android
Are you? From the Android docs
However, since the user is not directly aware of a background service, in that state it is considered a valid candidate to kill, and you should be prepared for this to happen. In particular, long-running services will be increasingly likely to kill and are guaranteed to be killed (and restarted if appropriate) if they remain started long enough.
Three days seems like it would fall under "long-running...guaranteed to be killed".
If the problem is not that your service is killed but that it isn't restarted, you could use the AlarmManager to regularly check the status of your service and restart, if necessary.

Categories

Resources