Background Apps? | Android Central Forum
Any way to see which app are running in background and block them?
Stop background apps from running - non-root Android
How to make an android app to always run in background? - Stack Overflow
Videos
Hi everyone, I wanted to know if there is any way to check which apps are currently running in background and eventually force closing them if I don't care about them. Can you suggest me any app that can do that?
Is there any app for Android (non-root) able to stop applications from running in background?
Battery Tool (on F-Droid) works only on rooted systems
Thanks
You have to start a service in your Application class to run it always. If you do that, your service will be always running. Even though user terminates your app from task manager or force stop your app, it will start running again.
Create a service:
public class YourService extends Service {
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
// do your jobs here
return super.onStartCommand(intent, flags, startId);
}
}
Create an Application class and start your service:
public class App extends Application {
@Override
public void onCreate() {
super.onCreate();
startService(new Intent(this, YourService.class));
}
}
Add "name" attribute into the "application" tag of your AndroidManifest.xml
android:name=".App"
Also, don't forget to add your service in the "application" tag of your AndroidManifest.xml
<service android:name=".YourService"/>
And also this permission request in the "manifest" tag (if API level 28 or higher):
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
UPDATE
After Android Oreo, Google introduced some background limitations. Therefore, this solution above won't work probably. When a user kills your app from task manager, Android System will kill your service as well. If you want to run a service which is always alive in the background. You have to run a foreground service with showing an ongoing notification. So, edit your service like below.
public class YourService extends Service {
private static final int NOTIF_ID = 1;
private static final String NOTIF_CHANNEL_ID = "Channel_Id";
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public int onStartCommand(Intent intent, int flags, int startId){
// do your jobs here
startForeground();
return super.onStartCommand(intent, flags, startId);
}
private void startForeground() {
Intent notificationIntent = new Intent(this, MainActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0,
notificationIntent, 0);
startForeground(NOTIF_ID, new NotificationCompat.Builder(this,
NOTIF_CHANNEL_ID) // don't forget create a notification channel first
.setOngoing(true)
.setSmallIcon(R.drawable.ic_notification)
.setContentTitle(getString(R.string.app_name))
.setContentText("Service is running background")
.setContentIntent(pendingIntent)
.build());
}
}
EDIT: RESTRICTED OEMS
Unfortunately, some OEMs (Xiaomi, OnePlus, Samsung, Huawei etc.) restrict background operations due to provide longer battery life. There is no proper solution for these OEMs. Users need to allow some special permissions that are specific for OEMs or they need to add your app into whitelisted app list by device settings. You can find more detail information from https://dontkillmyapp.com/.
If background operations are an obligation for you, you need to explain it to your users why your feature is not working and how they can enable your feature by allowing those permissions. I suggest you to use AutoStarter library (https://github.com/judemanutd/AutoStarter) in order to redirect your users regarding permissions page easily from your app.
By the way, if you need to run some periodic work instead of having continuous background job. You better take a look WorkManager (https://developer.android.com/topic/libraries/architecture/workmanager)
On some mobiles like mine (MIUI Redmi 3) you can just add specific Application on list where application doesnt stop when you terminate applactions in Task Manager (It will stop but it will start again)
Just go to Settings>PermissionsAutostart
Well, this sure enough confirmed my hypothesis of "if no one on stackexchange knows the answer, you're going to have to figure it out yourself".
So I did.
The answer to this question is twofold. There's the window manager and the activity manager, and both play a certain role in this.
While it was tempting to write a TL;DR at the top here, I didn't, because especially with the second part, you have to be very careful with what you're doing, at least for now.
Window Manager/Recent Tasks
Let's start with the window manager, as this will also be interesting for people without large amounts of RAM. Also, it's quite a bit simpler.
It works with a number of variables: config_activeTaskDurationHours as well as a number of NumVisibleRecentTasks variables. config_activeTaskDurationHours determines, as the name suggests, how long a task is considered active, that is, relevant to the user. On my device, this was set to 6. After those 6 hours, the "task" no longer appears in the recent apps list, with one exception: the number of open apps would be lower than, in my case, config_minNumVisibleRecentTasks, launcher included. In that case, the app is not discarded. If the number of open apps is the same as config_minNumVisibleRecentTasks, though, then as soon as you open an app that isn't opened yet, the oldest open app that hasn't been used for more than 6 hours is discarded.
There are also a couple of other related settings that weren't relevant in my case:
config_minNumVisibleRecentTasks_grid: This is for when apps are displayed in a grid. This view is not available on many builds of Android, though.config_minNumVisibleRecentTasks_lowRam: The same setting for low RAM devices.config_maxNumVisibleRecentTasks,config_maxNumVisibleRecentTasks_grid, andconfig_maxNumVisibleRecentTasks_lowRam: these are upper limits for the numbers of recent tasks. In my caseconfig_maxNumVisibleRecentTaskswas set to -1, which means there is no maximum limit.
These are all grabbed from resources, and can be modified with GravityBox (root and XPosed/EdExposed/LSPosed required), under the Advanced tuning section, in the Framework section. They require a restart to activate the changes.
In my case, I set both config_activeTaskDurationHours and config_minNumVisibleRecentTasks to a ridiculous level: 5000. That way, it takes over a half a year for a task to have a chance to be removed, and that only if there are more than 5000 apps open, which I suspect will never happen.
Activity Manager/OomAdjuster
This was a bit of a tougher nut to crack for me, and took a good amount of searching through the source code to find the answer - although the answer may not have really required it. Oh, well.
I first tried writing an XPosed module to override com.android.server.am.ActivityManagerConstants, specifically updateMaxCachedProcesses. Unfortunately, I couldn't get it to hook the method properly, I don't know why. Mind you, I've never tried writing an XPosed module before, and I did this with AIDE - maybe sometime I'll unpack Android Studio again and try it in there. But if anyone wants finer control, this should offer an avenue to do that.
At the end, my original suspicion that you might be able to use the background process limit unoficially to increase the limit ended up being true. Sure enough, if you go into developer settings and change the background process limit to, say, 4, the output of su -c dumpsys activity settings looks like this at the end:
mOverrideMaxCachedProcesses=4
CUR_MAX_CACHED_PROCESSES=4
CUR_MAX_EMPTY_PROCESSES=2
CUR_TRIM_EMPTY_PROCESSES=15
CUR_TRIM_CACHED_PROCESSES=10
Note that the trim levels aren't changed, and IMO it doesn't make sense to change those levels even if the device has a high amount of RAM. Essentially, if the process numbers are below the trim levels, the system doesn't even bother trimming memory.
So, how can we assign a higher value? This is where things get complicated. I tried to call ActivityManager.setProcessLimit() with the permission android.permission.SET_PROCESS_LIMIT (which is only available to system apps but can also be granted via ADB) as defined in the IActivityManager Interface, but I couldn't get it to work (again, I was working with AIDE, so that may be the problem, I may try it again on Android Studio later).
However, there is a little known android shell command, service call, which essentially lets you call a whole bunch of methods from different service interfaces, see Where to find info on Android's "service call" shell command?. What you're looking for is the activity service, which is defined in android.app.IActivityManager.aidl, and you're looking for the method setProcessLimit(int max). Using the terminal, we can do service list to get a list of the services that can be called here. In my case, the service name I'm looking for was activity. Then, we look up the setProcessLimit(int max) command in the source code. Since I'm reasonably close to AOSP, I can look it up in there. In my case, it's the 40th command.
WARNING: Before I show what I needed for my device, don't just blindly follow this. This is different for just about every version of Android, and if you mess it up, it could cause problems. Read the link from the paragraph beforehand to be sure, at the very least be sure to understand my explanation in the previous paragraph.
In my case, I decided to set it to something ridiculous, so I took the tenfold of the original value, 600. That turned it into: service call activity 40 i32 600 (be sure to run su before that as this needs root privileges). Now, when I call su -c dumpsys activity settings, the section looks like this:
mOverrideMaxCachedProcesses=600
CUR_MAX_CACHED_PROCESSES=600
CUR_MAX_EMPTY_PROCESSES=300
CUR_TRIM_EMPTY_PROCESSES=15
CUR_TRIM_CACHED_PROCESSES=10
Halleluja! We did it! Mind you, AFAIK, you'll have to repeat the service call command on every restart, and if you mess around with the background process limit setting in developer settings, you'll also lose what you just set.
Maybe someday I'll try the approach with a root/adb app or an XPosed module again, and If I do, I'll update this answer. But for now, I'm happy with the results. RAM usage is now more between 5.5 and 6GB, as opposed to 4GB. Apps seem to be restarting less. Life is better.
I updated my module that's been mentioned in the original question and actually there's a way to set max_cached_processes to a value that survives restarts - even without root, with simple adb commands. Check the module's documentation and all the links lead me to the solution. Cheers!
Android 9 and below:
settings put global activity_manager_constants max_cached_processes=256
Android 10 and above:
/system/bin/device_config put activity_manager max_phantom_processes 2147483647
/system/bin/device_config put activity_manager max_cached_processes 256
Or something like this:
[ $(getprop ro.build.version.release) -gt 9 ] && cmd device_config set_sync_disabled_for_tests persistent
[ $(getprop ro.build.version.release) -gt 9 ] && cmd device_config put activity_manager max_cached_processes 256 || settings put global activity_manager_constants max_cached_processes=256
[ $(getprop ro.build.version.release) -gt 9 ] && cmd device_config put activity_manager max_phantom_processes 2147483647
[ $(getprop ro.build.version.release) -gt 9 ] && cmd settings put global settings_enable_monitor_phantom_procs false
[ $(getprop ro.build.version.release) -gt 9 ] && cmd device_config put activity_manager max_empty_time_millis 43200000
[ $(getprop ro.build.version.release) -gt 9 ] && cmd settings put global settings_enable_monitor_phantom_procs false