I have Android application with some services that bind to some process.
I found that adb shell top -n 1
returns:
PID PR CPU% S #THR VSS RSS PCY UID Name
31647 0 1% S 70 1733640K 98960K bg u0_a132 com.my.app.dev
31727 0 1% S 29 1523892K 62924K fg u0_a132 com.my.app.dev:myService
Even when my application stays in background, why top
PCY
tells 'fg'
a.e. foreground?
Can somebody spread the light on this issue?
This is my Manifest.xml:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.my.app.dev"
android:versionName="4.0.1.6700000"
android:versionCode="5033" >
<uses-sdk android:minSdkVersion="10"
android:targetSdkVersion="16" />
<application android:icon="@drawable/icon"
android:label="@string/config_app_name"
android:theme="@style/Theme.NoActionBarAppCompat"
android:name="com.my.app.Mine" >
<!-- we would prefer the launchMode to be standard, but it causes a lot of problems. -->
<activity android:name="com.my.ui.main.MineApp"
android:label="@string/config_app_name"
android:launchMode="singleTask"
android:clearTaskOnLaunch="true"
android:theme="@style/Theme.Translucent.NoActionBarAppCompat" >
<intent-filter>
<category android:name="android.intent.category.DEFAULT" />
<action android:name="mine.action.HomeActivity" />
<category android:name="android.intent.category.LAUNCHER" />
<action android:name="android.intent.action.MAIN" />
</intent-filter>
</activity>
<meta-data android:name="com.google.android.maps.v2.API_KEY"
android:value="xxxxxx" />
<meta-data android:name="com.google.android.gms.version"
android:value="@integer/google_play_services_version" />
<uses-library android:name="com.google.android.maps" />
<service android:name="com.my.engine.logic.EngineService"
android:process=":myService">
<intent-filter>
<action android:name="com_my_RemoteService" />
<action android:name="com_my_EngineService" />
</intent-filter>
</service>
<receiver
android:name="com.my.engine.analytics.ReferrerReceiver"
android:exported="true" android:process=":myService">
<intent-filter>
<action
android:name="com.android.vending.INSTALL_REFERRER"/>
</intent-filter>
</receiver>
<receiver
android:name="com.my.engine.BootBroadcastReceiver"
android:process=":myService">
<intent-filter>
<action
android:name="android.intent.action.BOOT_COMPLETED"/>
</intent-filter>
</receiver>
<receiver
android:name="com.my.engine.util.MineWatcherReceiver"
android:process=":myServiceWatcher">
<intent-filter>
<action
android:name="android.intent.action.ACTION_POWER_CONNECTED" />
<action
android:name="android.intent.action.BATTERY_OKAY" />
<action
android:name="android.net.conn.CONNECTIVITY_CHANGE" />
<action
android:name="android.intent.action.USER_PRESENT" />
</intent-filter>
</receiver>
<receiver
android:name="com.my.engine.logic.InitServiceReceiver"
android:exported="true" android:process=":myService">
<intent-filter>
<action android:name="initServiceCheck"/>
</intent-filter>
</receiver>
<receiver
android:name="com.my.engine.logic.UpdateCounterReceiver"
android:exported="true" android:process=":myService">
<intent-filter>
<action android:name="updateCustomCounter"/>
</intent-filter>
</receiver>
<receiver
android:name="com.my.engine.logic.PackageChangeReceiver"
android:process=":myService">
<intent-filter>
<action
android:name="android.intent.action.PACKAGE_ADDED"/>
<action
android:name="android.intent.action.PACKAGE_REPLACED"/>
<action
android:name="android.intent.action.PACKAGE_REMOVED"/>
<action
android:name="android.intent.action.PACKAGE_INSTALL"/>
<data android:scheme="package"/>
</intent-filter>
</receiver>
<!-- for notification try next action -->
<service android:name="com.my.notifications.actions.TryNextNotificationActionService" />
<receiver android:name="com.my.ui.base.EulaReminderReceiver">
<intent-filter>
<action android:name="eulaReminderAction" />
</intent-filter>
</receiver>
<receiver android:name="com.my.ui.base.MineGuiBroadcastReceiver">
<intent-filter>
<action android:name="finishStoppedActivities" />
</intent-filter>
</receiver>
<service android:name="com.my.infra.motion.ActivityRecognitionService"
android:label="ActivityRecognitionService"
android:exported="true"
android:enabled="true"
android:process=":myService">
</service>
</application>
</manifest>
Edit 1
I even stopped Notifications from Settings but still process=":myService
in foreground
Edit 2
from sources:
if (p == SP_BACKGROUND)
strcpy(proc->policy, "bg");
else if (p == SP_FOREGROUND)
strcpy(proc->policy, "fg");
else
strcpy(proc->policy, "er");
from Answer in other question:
Mostly-uneducated-somewhat-random-stab-in-the-dark for PCY --
PCY -- Policy -- Determines how an app should be treated by Android's memory manager
FG -- Foreground -- Process is considered a foreground process and should not be killed to free memory
BG -- Background -- Process is considered a background process (not actively running in foreground and may be killed to free memory)
To elaborate on Alex P.'s answer:
I believe the PCY column refers to the cgroup
that the process is assigned to. Android defines two cgroup
groups, SP_FOREGROUND
and SP_BACKGROUND
. The actual cgroup
name for SP_BACKGROUND
is bg_non_interactive
. These groups are indicated in top
with the abbreviations fg
and bg
, respectively.
You can find references to these throughout the Framework, most notably in Process.java
, IPCThreadState.cpp
and the native code in android_util_Process.cpp
that interfaces with the Linux /proc
filesystem to manage various aspects of the running processes. According to source code commenting in these files, it seems that all threads in the foreground cgroup
are scheduled with a 'normal' share of the CPU, while those in the background cgroup
are scheduled with a 'reduced' share.
As for the definitions of normal and reduced, this blog states that SP_BACKGROUND
threads are limited to 5% CPU usage. You can confirm this by looking in /dev/cpuctl/bg_non_interactive/cpu.shares
on your running device. On my Nexus 5 running AOSP 5.1, I get:
root@hammerhead:/ # cat /dev/cpuctl/bg_non_interactive/cpu.shares
52
root@hammerhead:/ #
Here, 52 refers to the number of 'CPU shares' allowed for threads in the cgroup
, out of a maximum of 1024 shares. So in this case bg_non_interactive
threads are indeed allowed a maximum of ~5% CPU usage total for all the threads in the group.
In any case, it's clear that foreground and background in this context has little to do with Android's Activity lifecycle and the idea of foreground and background apps. It's simply the way that Android leverages Linux's cgroups
facility.