adb shell top在前台显示我的应用程序,但实际上是在后台

时间:2021-05-17 02:15:24

I have Android application with some services that bind to some process.

我有Android应用程序与一些绑定到某些进程的服务。

I found that adb shell top -n 1 returns:

我发现adb shell top -n 1返回:

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?

即使我的应用程序保留在后台,为什么*PCY会告诉'fg'a.e.前景?

Can somebody spread the light on this issue?

有人可以传播这个问题吗?

This is my Manifest.xml:

这是我的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

编辑1

I even stopped Notifications from Settings but still process=":myService in foreground

我甚至从设置中停止了通知,但仍处理=“:myService in foreground

Edit 2

编辑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来说,大部分没有受过教育 - 有点随意刺入黑暗中 -

PCY -- Policy -- Determines how an app should be treated by Android's memory manager

PCY - 策略 - 确定Android内存管理器应如何处理应用程序

FG -- Foreground -- Process is considered a foreground process and should not be killed to free memory

FG - 前景 - 进程被视为前台进程,不应该被释放以释放内存

BG -- Background -- Process is considered a background process (not actively running in foreground and may be killed to free memory)

BG - 后台 - 进程被视为后台进程(未在前台主动运行,可能会被释放以释放内存)

2 个解决方案

#1


3  

To elaborate on Alex P.'s answer:

详细阐述Alex P.的答案:

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.

我相信PCY列指的是进程被分配到的cgroup。 Android定义了两个cgroup组,SP_FOREGROUND和SP_BACKGROUND。 SP_BACKGROUND的实际cgroup名称是bg_non_interactive。这些组的顶部分别用缩写fg和bg表示。

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.

您可以在整个Framework中找到对这些的引用,最明显的是在Process.java,IPCThreadState.cpp和android_util_Process.cpp中的本机代码,它们与Linux / proc文件系统接口以管理正在运行的进程的各个方面。根据这些文件中的源代码注释,似乎前台cgroup中的所有线程都使用CPU的“正常”份额进行调度,而后台cgroup中的所有线程都使用“减少”份额进行调度。

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:

至于normal和reduced的定义,这篇博客指出SP_BACKGROUND线程的CPU使用率限制为5%。您可以通过查看正在运行的设备上的/dev/cpuctl/bg_non_interactive/cpu.shares来确认这一点。在运行AOSP 5.1的Nexus 5上,我得到:

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.

这里,52指的是cgroup中允许线程允许的“CPU份额”数,最多为1024份。因此,在这种情况下,bg_non_interactive线程确实允许组中所有线程的最大CPU使用率约为5%。

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.

无论如何,很明显,这个上下文中的前景和背景与Android的Activity生命周期以及前景和后台应用程序的想法几乎没有关系。这就是Android利用Linux的cgroups设施的方式。

#2


2  

PCY stands for scheduling policy. fg in that column means that the process gets higher priority than bg. It does not mean that the process is running in foreground.

PCY代表调度策略。该列中的fg表示该进程的优先级高于bg。这并不意味着进程在前台运行。

#1


3  

To elaborate on Alex P.'s answer:

详细阐述Alex P.的答案:

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.

我相信PCY列指的是进程被分配到的cgroup。 Android定义了两个cgroup组,SP_FOREGROUND和SP_BACKGROUND。 SP_BACKGROUND的实际cgroup名称是bg_non_interactive。这些组的顶部分别用缩写fg和bg表示。

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.

您可以在整个Framework中找到对这些的引用,最明显的是在Process.java,IPCThreadState.cpp和android_util_Process.cpp中的本机代码,它们与Linux / proc文件系统接口以管理正在运行的进程的各个方面。根据这些文件中的源代码注释,似乎前台cgroup中的所有线程都使用CPU的“正常”份额进行调度,而后台cgroup中的所有线程都使用“减少”份额进行调度。

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:

至于normal和reduced的定义,这篇博客指出SP_BACKGROUND线程的CPU使用率限制为5%。您可以通过查看正在运行的设备上的/dev/cpuctl/bg_non_interactive/cpu.shares来确认这一点。在运行AOSP 5.1的Nexus 5上,我得到:

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.

这里,52指的是cgroup中允许线程允许的“CPU份额”数,最多为1024份。因此,在这种情况下,bg_non_interactive线程确实允许组中所有线程的最大CPU使用率约为5%。

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.

无论如何,很明显,这个上下文中的前景和背景与Android的Activity生命周期以及前景和后台应用程序的想法几乎没有关系。这就是Android利用Linux的cgroups设施的方式。

#2


2  

PCY stands for scheduling policy. fg in that column means that the process gets higher priority than bg. It does not mean that the process is running in foreground.

PCY代表调度策略。该列中的fg表示该进程的优先级高于bg。这并不意味着进程在前台运行。