2

いくつかのプロセスにバインドするいくつかのサービスを備えた Android アプリケーションがあります。

私はそれ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

アプリケーションがバックグラウンドにある場合でも、なぜtop PCYae が'fg'フォアグラウンドに表示されるのですか?

誰かがこの問題について光を広めることができますか?

これは私の 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

ソースから:

if (p == SP_BACKGROUND)
        strcpy(proc->policy, "bg");
    else if (p == SP_FOREGROUND)
        strcpy(proc->policy, "fg");
    else
        strcpy(proc->policy, "er");

他の質問の回答から :

ほとんど教育を受けていない、やや無作法な PCY の暗黒面での刺し傷 --

PCY -- ポリシー -- Android のメモリ マネージャーによるアプリの処理方法を決定します。

FG -- フォアグラウンド -- プロセスはフォアグラウンド プロセスと見なされ、メモリを解放するために強制終了されるべきではありません

BG -- バックグラウンド -- プロセスはバックグラウンド プロセスと見なされます (フォアグラウンドでアクティブに実行されておらず、メモリを解放するために強制終了される場合があります)

4

2 に答える 2

2

Alex P.の答えを詳しく説明するには:

PCY列はcgroup、プロセスが割り当てられていることを指していると思います。Android は 2 つのcgroupグループを定義SP_FOREGROUNDSP_BACKGROUNDます。の実際のcgroup名前はSP_BACKGROUNDですbg_non_interactive。これらのグループは、それぞれtop略語fgおよびで示されbgます。

フレームワーク全体でこれらへの参照を見つけることができますがProcess.java、特に. これらのファイルのソース コードのコメントによると、フォアグラウンドのすべてのスレッドは CPU の「通常の」シェアでスケジュールされ、バックグラウンドのスレッドは「削減された」シェアでスケジュールされているようです。IPCThreadState.cppandroid_util_Process.cpp/proccgroupcgroup

通常と削減の定義については、このブログでは、SP_BACKGROUNDスレッドが 5% の CPU 使用率に制限されていると述べています。/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:/ #

cgroupここで、52 は、最大 1024 の共有のうち、 のスレッドに許可される「CPU 共有」の数を指します。したがって、この場合bg_non_interactive、スレッドは、グループ内のすべてのスレッドの合計で最大 ~5% の CPU 使用率が実際に許可されます。

いずれにせよ、この文脈におけるフォアグラウンドとバックグラウンドは、Android のアクティビティ ライフサイクルや、フォアグラウンド アプリとバックグラウンド アプリの概念とはほとんど関係がないことは明らかです。これは、Android が Linux のcgroups機能を活用する方法にすぎません。

于 2015-09-21T19:25:24.060 に答える