具有启动服务的 Android 进程重要性不是 IMPORTANCE_SERVICE

标签 android android-service background-process

我正在尝试更好地理解 android 中的进程优先级,尤其是当服务在 Activity 所在的同一进程中运行时。

Android 文档解释说,当有服务启动并且应用程序进入后台时,该进程将是一个“服务进程”,相对于正常的后台进程具有更高的级别。

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

Process Lifecycle

3. Service process
A process that is running a service that has been started with the startService() method and does not fall into either of the two higher categories. Although service processes are not directly tied to anything the user sees, they are generally doing things that the user cares about (such as playing music in the background or downloading data on the network), so the system keeps them running unless there's not enough memory to retain them along with all foreground and visible processes.

...

Because a process running a service is ranked higher than a process with background activities, an activity that initiates a long-running operation might do well to start a service for that operation, rather than simply create a worker thread—particularly if the operation will likely outlast the activity.

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

  • If the service has been started, then its hosting process is considered to be less important than any processes that are currently visible to the user on-screen, but more important than any process not visible. Because only a few processes are generally visible to the user, this means that the service should not be killed except in extreme low memory conditions.

为了确保这一点,我做了一个简单的测试,在一个应用程序中,我用 startService 启动了一个本地内部服务。并将应用程序置于后台,同时每秒打印一次 ActivityManager.RunningAppProcessInfo .

我期待 importance该过程将变为 IMPORTANCE_SERVICE但我得到了IMPORTANCE_BACKGROUND .

为什么会这样?
文档有误吗?
即使我得到 IMPORTANCE_BACKGROUND,该过程在任何情况下都比后台的其他过程更重要,因此使用本地服务仍然更可取?

编辑:这是一个示例代码

list 声明:

<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;
    }

}

Activity :

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);
        }
    };
}

最佳答案

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

关于具有启动服务的 Android 进程重要性不是 IMPORTANCE_SERVICE,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24587507/

相关文章:

android - Listview 只显示列表中的一行

java - 如何将可变参数传递给观察者?

java - 访问网络状态时出错

Android Service 一次又一次地创造

android - 在 Android O 中发送本地通知

bash + expect,后台运行

java - 关于 LibGdx addListener

java - 不使用服务的后台任务 - Android

android - 如何将字符串从 fragment 传递到android中的服务

bash - 使用后台进程退出 shell 脚本