启动服务的Android流程重要性不是IMPORTANCE_SERVICE

时间:2014-07-05 14:42:07

标签: android android-service background-process

我试图更好地理解android中的进程优先级,尤其是当有一个服务在活动所在的同一进程中运行时。

Android文档解释说,当服务启动且应用程序在后台运行时,该过程将是一个"服务流程"在正常的背景过程中具有更高的等级。

http://developer.android.com/guide/components/processes-and-threads.html

流程生命周期

3. 服务流程
正在运行已使用startService()方法启动的服务的进程,并且不属于上述两个类别中的任何一个。虽然服务流程并不直接与用户看到的任何内容联系在一起,但它们通常是在做一些用户关心的事情(例如在后台播放音乐或在网络上下载数据),因此系统会保持运行,除非“没有足够的内存来保留它们以及所有前景和可见进程。

...

因为运行服务的进程的排名高于具有后台活动的进程,所以启动长时间运行的活动可能会为该操作启动服务,而不是简单地创建工作线程 - 特别是如果操作可能比活动寿命长。

  

http://developer.android.com/reference/android/app/Service.html

     
      
  • 如果服务已经启动,则其托管过程被认为不如屏幕上用户当前可见的任何进程重要,但比任何不可见的进程更重要。因为用户通常只能看到一些进程,这意味着除非在极低内存条件下,否则不应该终止服务。
  •   

为了确保我已经完成了一项简单的测试,我在应用程序内部使用startService启动了本地内部服务,并将应用程序置于后台,同时每秒打印一次ActivityManager.RunningAppProcessInfo

我原以为该流程的importance会变为IMPORTANCE_SERVICE,但我得到IMPORTANCE_BACKGROUND

为什么会这样? 文件是否错误?
即使我获得了IMPORTANCE_BACKGROUND,这个过程在任何情况下都比后者更重要,所以仍然可以使用本地服务吗?

编辑:以下是一个示例代码

清单声明:

<service android:name=".EmptyService" android:exported="false" />

服务:

public class EmptyService extends Service {

    private static final String TAG = "EmptyService";

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        // empty service that is never stopped
        return START_NOT_STICKY;
    }
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

}

的活动:

public class MyActivity extends Activity {

    private static final String TAG = "MyActivity";

    private final Handler mHandler = new Handler();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_my);

        startService(new Intent(this, EmptyService.class));
        mImportanceLogger.run();
    }

    private final Runnable mImportanceLogger = new Runnable() {
        @Override
        public void run() {
            final ActivityManager am = (ActivityManager) MyActivity.this.getSystemService(ACTIVITY_SERVICE);
            final List l = am.getRunningAppProcesses();
            final Iterator i = l.iterator();
            while(i.hasNext()) {
                final ActivityManager.RunningAppProcessInfo info = (ActivityManager.RunningAppProcessInfo)(i.next());
                if (info.processName.contains("serviceimportance")) {
                    // importance is 100 (IMPORTANCE_FOREGROUND) when the activity is visibile
                    // importance is 400 (IMPORTANCE_BACKGROUND) when the activity is in background
                    // but in the latter case i was expecting 300 (IMPORTANCE_SERVICE) because
                    // there is a service running
                    Log.i(TAG, info.processName + " importance " + info.importance + " importanceReason " + info.importanceReasonCode);
                }
            }

            mHandler.postDelayed(mImportanceLogger, 2000);
        }
    };
}

1 个答案:

答案 0 :(得分:1)

我使用 adb shell dumpsys activity p 玩了一下,发现当有启动服务时,活动管理器会将流程标记为 cch-started-ui-services
此外,您可以通过简单地查看基于第一个lru值(在dumpsys cch + 1,cch + 2等中)来了解应用程序进程优先于没有服务的后台进程。 >在包含服务的流程上,然后在不包含任何已启动服务的流程上。