开启前台Service

栏目: Android · 发布时间: 6年前

内容简介:将在在

Service

DaemonService 设置为前台服务,主要为了减小 oom_adj 值(oom_adj越小优先级越高),增加应用存活几率。在API为18或更高的版本,此方法会显示可见通知。为避免打扰用户,一般会启动另一个Service把出现的通知移除。最终达到通知栏没有常驻通知,但是oom_adj值减少的目的。

class DaemonService : Service() {

    override fun onCreate() {
        super.onCreate()

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
            val builder = Notification.Builder(this)
            builder.setSmallIcon(R.mipmap.ic_launcher)
            builder.setContentTitle(TAG)
            builder.setContentText(DESCRIPTION)
            startForeground(NOTIFICATION_ID, builder.build())
            startService(Intent(this, CancelNoticeService::class.java))
        } else if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR2) {
            startForeground(NOTIFICATION_ID, Notification())
        }
    }

    // 返回START_STICKY
    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int) = START_STICKY

    override fun onDestroy() {
        super.onDestroy()

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
            val manager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
            manager.cancel(NOTIFICATION_ID)
        }

        startService(Intent(applicationContext, DaemonService::class.java))
    }

    override fun onBind(intent: Intent?) = null

    companion object {
        const val TAG = "DaemonService"
        const val NOTIFICATION_ID = 1024
        const val NOTIFICATION_ID_STR = "DaemonService"
        const val DESCRIPTION = "DaemonService is running."
    }
}

DaemonService 启动后会触发 CancelNoticeService 的启动。 CancelNoticeService 会在子线程中通过相同 NotificationId 移除已经出现的通知栏,达到隐藏的效果。由于通知栏出现和隐藏的时间间隔很短,所以用户一般不会察觉。

class CancelNoticeService : Service() {

    override fun onBind(intent: Intent?) = null

    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
        if (Build.VERSION.SDK_INT > Build.VERSION_CODES.JELLY_BEAN_MR2) {
            val builder = Notification.Builder(this)
            builder.setSmallIcon(R.mipmap.ic_launcher)
            startForeground(DaemonService.NOTIFICATION_ID, builder.build())

            Thread(Runnable {
                stopForeground(true)
                val manager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
                manager.cancel(DaemonService.NOTIFICATION_ID)

                // 结束服务
                stopSelf()
            }).start()
        }

        return super.onStartCommand(intent, flags, startId)
    }
}

调用

AndroidManifest.xml 注册以上两个Service。 DaemonService 要放在主进程,通过 DaemonService 的前台可见属性提升主进程优先级。

<service
    android:name=".services.DaemonService"
    android:enabled="true"
    android:exported="true" />

<service
    android:name=".services.CancelNoticeService"
    android:enabled="true"
    android:exported="true" />

MainActivity 启动 DaemonService

val i = Intent(this, DaemonService::class.java)
ContextCompat.startForegroundService(this, i)

结果

根据实际测试,以上方法只能在 Android 7.0 或以下版本使用。 Android 7.1.1 真机和模拟器测试通知均会出现,可知该方法从 Android 7.1.1 开始不起效。

以下结果在 Android 5.0 上测试:

user@MacBook-Pro:/ # adb shell
shell@generic_x86:/ # su
root@generic_x86:/ # ps | grep playground
u0_a55    2919  1263  1283232 45972 SyS_epoll_ b7377fa5 S com.phantomvk.playground

应用进入后台,Service尚未启动

root@generic_x86:/ # cat /proc/2919/oom_adj
6

应用对用户可见,并启动Service。前台界面对用户可见就为0,不受Service影响。

root@generic_x86:/ # cat /proc/2919/oom_adj
0

应用进入后台,Activity所在进程 oom_adj 从6变为1

root@generic_x86:/ # cat /proc/2919/oom_adj
1

经过一段时间测试,虽然主进程 oom_adj 能保持1,但在设备可用内存低时,还是出现应用被回收的现象。不过,对比没有保护的应用,使用以上方法后被杀的时间点明显延后很多。


以上所述就是小编给大家介绍的《开启前台Service》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Python机器学习基础教程

Python机器学习基础教程

[德]安德里亚斯·穆勒、[美]莎拉·吉多 / 张亮 / 人民邮电出版社 / 2018-1 / 79.00元

本书是机器学习入门书,以Python语言介绍。主要内容包括:机器学习的基本概念及其应用;实践中最常用的机器学习算法以及这些算法的优缺点;在机器学习中待处理数据的呈现方式的重要性,以及应重点关注数据的哪些方面;模型评估和调参的高级方法,重点讲解交叉验证和网格搜索;管道的概念;如何将前面各章的方法应用到文本数据上,还介绍了一些文本特有的处理方法。一起来看看 《Python机器学习基础教程》 这本书的介绍吧!

XML、JSON 在线转换
XML、JSON 在线转换

在线XML、JSON转换工具

XML 在线格式化
XML 在线格式化

在线 XML 格式化压缩工具

Markdown 在线编辑器
Markdown 在线编辑器

Markdown 在线编辑器