更新于 
部分信息可能已经过时,请谨慎参考本文内容。

客户端保活最佳方案机制

更优雅的利用系统机制保活

使用场景

一个云控脚本引擎

需求目的

需要让程序一直在后台运行保持不被系统杀死 避免让用户在使用过程中还需时刻盯着程序 造成不必要的繁琐问题 以达到配置好相关信息后只需提供设备电量 后续便可不用碰设备 实现远程云控效果

相关问题

  • 这年头还研究保活是想用户设备发热发烫么
    嗯 从使用场景来看 对用户而言最重要的能够随时接收命令 愿意使用就相当于接受了这一缺点
  • 双进程感觉挺靠谱的 有很多人也推这个保活机制
    使用场景不同 对用户造成的观感会有很大差别

参考实现

音乐类程序例如QQ音乐能一直在后台播放

相关代码

  • 代码区
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    class SilentMusicService : Service() {
    private var mMediaPlayer: MediaPlayer? = null
    private var mAudioManager: AudioManager? = null
    private lateinit var notificationBuilder: NotificationCompat.Builder
    private val mAudioFocusChange: OnAudioFocusChangeListener =
    object : OnAudioFocusChangeListener {
    override fun onAudioFocusChange(focusChange: Int) {
    when (focusChange) {
    AudioManager.AUDIOFOCUS_GAIN -> {
    try {
    startPlayMusic()
    } catch (e: Exception) {
    e.printStackTrace()
    }
    }
    AudioManager.AUDIOFOCUS_LOSS -> {
    mAudioManager!!.abandonAudioFocus(this)
    }
    }
    }
    }

    override fun onBind(intent: Intent): IBinder? {
    throw UnsupportedOperationException("Not yet implemented")
    }

    @RequiresApi(Build.VERSION_CODES.O)
    override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int {
    NotificationUtils.notify(0) { param ->
    intent.putExtra("id", 0)
    notificationBuilder = param.setSmallIcon(R.mipmap.ic_launcher)
    .setContentText(R.string.this_is_a_running_foreground_process.toText())
    .setAutoCancel(false)
    .setOngoing(true)
    }
    NotificationUtils.cancelAll()
    startForeground(1, notificationBuilder.notification)
    mAudioManager = getSystemService(AUDIO_SERVICE) as AudioManager
    if (mAudioManager != null) mAudioManager!!.requestAudioFocus(
    mAudioFocusChange,
    AudioManager.STREAM_MUSIC,
    AudioManager.AUDIOFOCUS_GAIN
    )
    mMediaPlayer = MediaPlayer.create(applicationContext, R.raw.no_notice)
    mMediaPlayer?.isLooping = true
    startPlayMusic()
    return START_STICKY
    }

    private fun startPlayMusic() {
    if (mMediaPlayer != null && !mMediaPlayer!!.isPlaying) {
    mMediaPlayer!!.start()
    }
    }

    private fun stopPlayMusic() {
    if (mMediaPlayer != null) {
    mMediaPlayer!!.stop()
    }
    }

    override fun onDestroy() {
    super.onDestroy()
    stopPlayMusic()
    startService(Intent(this, SilentMusicService::class.java))
    }
    }
  • 清单区
    1
    2
    3
    4
    5
    <service
    android:name=".service.SilentMusicService"
    android:priority="1000"
    android:enabled="true"
    android:process=":musicService"/>

测试结果

机型品牌系统版本成果
HUAWEI7.0 8.1 9.0可长时间运转完成任务
Redmi9.0 10 11可长时间运转完成任务(10以上添加另外的保活配置)
Vivo、OPPO10可长时间运转完成任务(测试次数过少)