adb shell top 在前台显示我的应用程序,但实际上它在后台
adb shell top shows my application in foreground but actually its in background
我有 Android 应用程序,其中包含一些绑定到某个进程的服务。
我发现 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
即使我的应用程序停留在后台,为什么 top
PCY
告诉 'fg'
a.e。前景?
有人可以阐明这个问题吗?
这是我的 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>
编辑 1
我什至停止了来自设置的通知,但仍然 process=":myService
在前台
编辑 2
来自 sources:
if (p == SP_BACKGROUND)
strcpy(proc->policy, "bg");
else if (p == SP_FOREGROUND)
strcpy(proc->policy, "fg");
else
strcpy(proc->policy, "er");
来自 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)
PCY
代表scheduling policy
。该列中的 fg
表示该进程的优先级高于 bg
。这并不意味着该进程在前台运行。
详细说明 Alex P. 的回答:
我相信 PCY 列指的是进程分配给的 cgroup
。 Android 定义了两个 cgroup
组,SP_FOREGROUND
和 SP_BACKGROUND
。 SP_BACKGROUND
的实际 cgroup
名称是 bg_non_interactive
。这些组在 top
中分别用缩写 fg
和 bg
表示。
您可以在整个框架中找到对这些内容的引用,最显着的是 Process.java
、IPCThreadState.cpp
和 android_util_Process.cpp
中与 Linux /proc
文件系统来管理 运行 进程的各个方面。根据这些文件中的源代码评论,似乎前台 cgroup
中的所有线程都安排了 CPU 的 'normal' 份额,而后台 cgroup
中的线程已安排 'reduced' 份额。
关于正常和减少的定义,this 博客指出 SP_BACKGROUND
线程被限制为 5% CPU 使用率。您可以通过在 运行 设备上查看 /dev/cpuctl/bg_non_interactive/cpu.shares
来确认这一点。在我的 Nexus 5 运行 AOSP 5.1 上,我得到:
root@hammerhead:/ # cat /dev/cpuctl/bg_non_interactive/cpu.shares
52
root@hammerhead:/ #
这里的52是指cgroup
线程允许的'CPU shares'个数,最多1024个。因此,在这种情况下,bg_non_interactive
个线程确实允许组中所有线程的最大 ~5% CPU 使用总量。
无论如何,很明显,此上下文中的前景和背景与 Android 的 Activity lifecycle 以及前景和背景应用程序的概念关系不大。这就是 Android 利用 Linux 的 cgroups
功能的简单方式。
我有 Android 应用程序,其中包含一些绑定到某个进程的服务。
我发现 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
即使我的应用程序停留在后台,为什么 top
PCY
告诉 'fg'
a.e。前景?
有人可以阐明这个问题吗?
这是我的 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>
编辑 1
我什至停止了来自设置的通知,但仍然 process=":myService
在前台
编辑 2
来自 sources:
if (p == SP_BACKGROUND)
strcpy(proc->policy, "bg");
else if (p == SP_FOREGROUND)
strcpy(proc->policy, "fg");
else
strcpy(proc->policy, "er");
来自 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)
PCY
代表scheduling policy
。该列中的 fg
表示该进程的优先级高于 bg
。这并不意味着该进程在前台运行。
详细说明 Alex P. 的回答:
我相信 PCY 列指的是进程分配给的 cgroup
。 Android 定义了两个 cgroup
组,SP_FOREGROUND
和 SP_BACKGROUND
。 SP_BACKGROUND
的实际 cgroup
名称是 bg_non_interactive
。这些组在 top
中分别用缩写 fg
和 bg
表示。
您可以在整个框架中找到对这些内容的引用,最显着的是 Process.java
、IPCThreadState.cpp
和 android_util_Process.cpp
中与 Linux /proc
文件系统来管理 运行 进程的各个方面。根据这些文件中的源代码评论,似乎前台 cgroup
中的所有线程都安排了 CPU 的 'normal' 份额,而后台 cgroup
中的线程已安排 'reduced' 份额。
关于正常和减少的定义,this 博客指出 SP_BACKGROUND
线程被限制为 5% CPU 使用率。您可以通过在 运行 设备上查看 /dev/cpuctl/bg_non_interactive/cpu.shares
来确认这一点。在我的 Nexus 5 运行 AOSP 5.1 上,我得到:
root@hammerhead:/ # cat /dev/cpuctl/bg_non_interactive/cpu.shares
52
root@hammerhead:/ #
这里的52是指cgroup
线程允许的'CPU shares'个数,最多1024个。因此,在这种情况下,bg_non_interactive
个线程确实允许组中所有线程的最大 ~5% CPU 使用总量。
无论如何,很明显,此上下文中的前景和背景与 Android 的 Activity lifecycle 以及前景和背景应用程序的概念关系不大。这就是 Android 利用 Linux 的 cgroups
功能的简单方式。