从android_bindservice_flag看oom_adj

本文对最近实现Service时遇到的一个小问题做一个记录。 主要以一个简单的demo讨论在bindService时,client和Service分处不同的进程,bindService传入的Flag分别对client进程和service进程的oom_adj值有什么影响。

我写了两个应用,A应用(com.test.serviceadjdemo_client)作为client存在,就一个按钮,点击按钮后调用bindService绑定B应用的一个服务。B应用(com.test.serviceadjdemo_service)也很简单,作为service存在,实现了被绑定的服务。下面看看当bindService传入不同的Flag时两个应用的oom_adj值有什么不同:

BIND_AUTO_CREATE

通过adb shell dumpsys meminfo查看进程的oom_adj: 启动A

    20094 kB: Foreground
               20094 kB: com.test.serviceadjdemo_client (pid 13687 / activities)

这里看到A应用的oom_adj理所应当是FOREGROUND_APP_ADJ。

点击按钮后通过bindService拉起B

    19430 kB: Foreground
               19430 kB: com.test.serviceadjdemo_client (pid 13687 / activities)
               
   331549 kB: Visible
				...
                5284 kB: com.test.serviceadjdemo_service (pid 14357)
                ...

这时候看到B应用被bindService拉起来了,并且B的oom_adj为VISIBLE_APP_ADJ,仅次于FOREGROUND_APP_ADJ。

BIND_AUTO_CREATE | BIND_ABOVE_CLIENT

启动A

        20331 kB: Foreground
               20331 kB: com.test.serviceadjdemo_client (pid 14631 / activities)

这里看到A应用的oom_adj理所应当是FOREGROUND_APP_ADJ。

点击按钮后通过bindService拉起B

     5324 kB: Foreground
                5324 kB: com.test.serviceadjdemo_service (pid 15078)

   332218 kB: Visible
			   ...
               19479 kB: com.test.serviceadjdemo_client (pid 14631 / activities)
               ...

这里看到神奇的事情就开始发生了,被拉起的B应用的oom_adj变成了FOREGROUND_APP_ADJ,在前台显示的A进程的oom_adj反而变成了VISIBLE_APP_ADJ。

BIND_AUTO_CREATE | BIND_IMPORTANT

启动A

            20255 kB: Foreground
               20255 kB: com.test.serviceadjdemo_client (pid 15849 / activities)

这里看到A应用的oom_adj理所应当是FOREGROUND_APP_ADJ。

点击按钮后通过bindService拉起B

    25441 kB: Foreground
               20096 kB: com.test.serviceadjdemo_client (pid 15849 / activities)
                5345 kB: com.test.serviceadjdemo_service (pid 15884)

这里看到神奇的事情又发生了,被拉起的B应用的oom_adj此时和A应用一样,都是FOREGROUND_APP_ADJ。

BIND_AUTO_CREATE | BIND_IMPORTANT | BIND_WAIVE_PRIORITY

启动A

    20226 kB: Foreground
               20226 kB: com.test.serviceadjdemo_client (pid 16372 / activities)

这里看到A应用的oom_adj理所应当是FOREGROUND_APP_ADJ。

点击按钮后通过bindService拉起B

    20023 kB: Foreground
               20023 kB: com.test.serviceadjdemo_client (pid 16372 / activities)

   332744 kB: Cached
                ...
                5400 kB: com.test.serviceadjdemo_service (pid 16403)
                ...

这里看到加入了BIND_WAIVE_PRIORITY后,BIND_IMPORTANT就失效了,新拉起来的B应用进程的oom_adj>=CACHED_APP_MIN_ADJ将被当做background进程去管理。

当组合为**BIND_AUTO_CREATE BIND_ABOVE_CLIENT BIND_WAIVE_PRIORITY**时其实效果跟上面一组一样,系统一样会把拉起来的B进程的oom_adj设置为>=CACHED_APP_MIN_ADJ,并且将B当做一个background进程去管理。

总结

本文刚好作为一个引子,引出后面的oom_adj系列的文章。在后面oom_adj系列的记录文章中,我将从:

谢谢大侠们赏脸看完,有理解偏差的地方多多指正。