1

Contrary to the traditional computing world, where programs won't quit without the user asking for it, in the mobile world (and Android in particular), it's generally considered up to the system to decide which app to quit and when, to the point where many if not most apps don't even have a quit option.

Up to some extent, it's justified due to :

  1. The limited amount of RAM available (contrary to the PC/Mac world where we've gone too far in the other direction, and the system by default considers a program can ask for as much virtual memory as it wants, which is a security problem, but that's another subject)
  2. The devices being for the general public, in a context where people don't necessarily have the knowledge/will/time to manage their phone usage on an app by app basis
  3. The apps are often designed to be used for short periods of time (which is linked to the previous point somehow)

However, there are cases where one doesn't want a given app to quit unless it's asked to explicitly by the end user. The reality of that need seems to have been taken into account by some mobile phone manufacturers (if I'm not mistaken, Samsung has been providing such an option for some time now).

So my question is : how shall I tell the system to not kill a given app ? I know there are apps that pretend to achieve this, but how shall I do that myself, without resorting to third party tools, only the stock Android command line tools and APIs ?

Afaik, there seem to be three criteria to decide to kill an app :

  1. Memory usage (the LMK daemon being in charge, unless a specific driver is present, in my case I have lmkd running)
  2. A limit on the number of running processes
  3. Battery optimisation, but there's already an option to disable that per-app, so I don't consider it a problem

So basically, only points 1 and 2 remain to be solved. You advices are welcome !

For what it's worth, I run Android x86 9.0 on an emulator (qemu).

EDIT : I checked the code of a program that's called App Settings, that's part of the Xposed framework. The program pretends to be able to set a program to stay resident in memory. After checking the code, it seems it modifies some application process attributes that are defined in the ProcessRecord class, namely maxAdj, curRawAdj, setRawAdj, curAdj and setAdj, setting those to the value of -12.

I wasn't able to test the program since my x86_64 Android 9.0 doesn't seem compatible with the framework, but I found this page, explaining in more detail how the activity manager service updates OOM values according to the app status, and communicates with LMK. It explains what the OOM values can be and what they mean. So clearly, trying to change the OOM values in /proc is useless, as the activity manager will change them, and probably LMK doesn't even read them anyway, and only takes what the activity manager transmits.

Is there any way to hint the Activity Manager into giving chosen OOM values to an app ? I could for example set the value to NATIVE_ADJ, or even no more than FOREGROUND_APP_ADJ at all times. Or maybe passing those parameters through a specially crafted intent ?

REEDIT : for those interested, the stop lmkd command should stop the LMK daemon until next reboot at least, which leaves only the OOM killer from Linux in charge. I didn't test it so I can't say for sure, but that should do it for some people. Beware of the consequences, however, if you continue using many apps at the same time, as a performance hit can be expected.

  • It's not the Android system which decides which app to quit. But it's the app developer who decides whether their app (or one of its specific functionality) should run in background or not. You are correct that end user cannot influence the decision much. If an app that should run in background but it doesn't, that's a poorly designed app. // OOM killer is also part of Linux kernel and every OS has some phenomenon to free RAM when needed. Android's LMKD operates in userspace because it provides more fine grained control over what to kill, asking system_server when making decisions. – Irfan Latif Apr 16 at 16:27
  • You can run a native process (like an init service) in background and that won't be killed (do take care of cgroups though). Exactly the same behavior as on a Linux PC. Android's decision to not let apps run in background is not only to free RAM but mainly to preserve battery. And also to provide user somewhat control on privacy i.e. what's happening in background without being noticed. Phones are 24/7 partners and hence perfect spying tools, PCs aren't. Btw I don't think there's a reliable way to prevent an app (which doesn't run a FG service) from being killed, even using 3rd party tools – Irfan Latif Apr 16 at 16:39
  • @IrfanLatif Thanks for your reply. However I'm not speaking about an app being able to run in the background, I don't have any problem with that, but I want to have an app in the foreground, switch to something else and be sure it will be still there when I switch back to it. It is able to leave the foreground, except the system sometimes decides to remove it, which is annoying. – NovHak Apr 16 at 22:38
  • 1
    Be aware of: dontkillmyapp.com realize that if the app is not actively on the screen, the app is in the Android Activity onPause state and may be killed. Programming related questions should be directed to stackoverflow.com/questions/tagged/android – Morrison Chang Apr 17 at 0:15
  • @NovHak alright. You talked about LMKD and number of running processes, so I gave an overview of lower level things according to my limited knowledge. Now what you state in comment is a trivial problem (there exist duplicate Qs) and is entirely handled by Android framework (as you figured out in your edit and as mentioned by MorrisonChang). The logic to control app killing behavior is hard-coded in AOSP and is made more forceful by OEMs. So the only way is to modify the source code of your ROM (if available). It's development oriented question, not meant for end users (whom this site is for). – Irfan Latif Apr 17 at 4:16

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.