Handler()在sreen关闭时在服务中的工作速度较慢

问题描述 投票:0回答:1

我提供的服务实际上是一个简单的后台计数器。

仅将1加到最后一个数字,然后转到UI。

我以前的问题是,当智能手机关闭或不充电时,Handler()有时工作非常缓慢。最近我找到了the same problem in this forum。我在服务中添加了PowerManager.WakeLock,并且一切正常...

但是我决定测试更长的时间,并同时在三部智能手机上启动该应用,并将其放置约一个半小时。当我回来时,我发现他们三个之间完全不同。

第一个显示5100(1小时25分钟),第二个显示2800(46分钟),第三个显示5660(1小时34分钟)。我非常确定唤醒锁将正确完成这项工作,但现在我不知道那里发生了什么。

这是我的服务代码:

class Timer_Service : Service() {
    companion object {
        val PARAM_OUT_MSG = "0"
    }
    var i = 0

    private lateinit var wakeLock: PowerManager.WakeLock
    private lateinit var mHandler: Handler
    private lateinit var mRunnable: Runnable

    override fun onBind(p0: Intent?): IBinder? {
        TODO("not implemented")
    }

    override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int {

        val powerManager = getSystemService(Context.POWER_SERVICE) as PowerManager
        wakeLock = powerManager.newWakeLock(
            PowerManager.PARTIAL_WAKE_LOCK,
            "ExampleApp:Wakelock"
        )
        wakeLock.acquire()

        val broadcastIntent = Intent()
        broadcastIntent.action = "com.example.infocell.action.RESPONSE"
        mHandler = Handler()
        mRunnable = Runnable {
            showOrderNumber()
            broadcastIntent.addCategory(Intent.CATEGORY_DEFAULT)
            broadcastIntent.putExtra(PARAM_OUT_MSG, i.toString())
            sendBroadcast(broadcastIntent)
        }
        mHandler.postDelayed(mRunnable, 1000)
        return START_NOT_STICKY
    }

    override fun onDestroy() {
        super.onDestroy()
        mHandler.removeCallbacks(mRunnable)
    }

    private fun showOrderNumber() {
        i += 1
        mHandler.postDelayed(mRunnable, 1000)
    }
}

清单还包含<uses-permission android:name="android.permission.WAKE_LOCK" />

android kotlin service foreground
1个回答
0
投票

最后经过各种测试,我得到了最精确的方法来做一个简单的计数器。我建议使用Handle()代替相对可靠的Timer()方法。在我所有的四款智能手机上,它的工作性能都绝对相等。为此还需要唤醒锁。我也将测试JobScheduler()CountDownTimer()以获取所有测试结果,但到目前为止我对计时器感到满意。

如果有人正在寻找此类任务的解决方案,我将共享我的代码。

class Timer_Service : Service() {
    companion object {
        val PARAM_OUT_MSG = "0"
    }
    var i = 0

    private lateinit var wakeLock: PowerManager.WakeLock
    private lateinit var timer: Timer

    override fun onBind(p0: Intent?): IBinder? {
        return null
    }

    override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int {
        val powerManager = getSystemService(Context.POWER_SERVICE) as PowerManager
        wakeLock = powerManager.newWakeLock(
            PowerManager.PARTIAL_WAKE_LOCK,
            "ExampleApp:Wakelock"
        )
        wakeLock.acquire()

        val broadcastIntent = Intent()
        broadcastIntent.action = "com.example.infocell.action.RESPONSE"

        timer = Timer()
        val task = object : TimerTask() {
            override fun run() {
                if (Trigger.getTrigger() == 0){
                    showOrderNumber()
                    // bring 'i' value to main activity
                    broadcastIntent.addCategory(Intent.CATEGORY_DEFAULT)
                    broadcastIntent.putExtra(PARAM_OUT_MSG, i.toString())
                    sendBroadcast(broadcastIntent)
                }
            }
        }
        timer.schedule(task,0, 1000)
        return START_STICKY
    }

    override fun onCreate() {
        super.onCreate()
        var notification = createNotification()
        startForeground(1, notification)
    }

    private fun createNotification(): Notification {
        val notificationChannelId = "ENDLESS SERVICE CHANNEL"

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager;
            val channel = NotificationChannel(
                notificationChannelId,
                "My Service",
                NotificationManager.IMPORTANCE_HIGH
            ).let {
                it.description = "Service channel"
                it.enableLights(true)
                it.lightColor = Color.RED
                it.enableVibration(true)
                it.vibrationPattern = longArrayOf(100)
                it
            }
            notificationManager.createNotificationChannel(channel)
        }

        val pendingIntent: PendingIntent = Intent(this, MainActivity::class.java).let { notificationIntent ->
            PendingIntent.getActivity(this, 0, notificationIntent, 0)
        }

        val builder: Notification.Builder = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) Notification.Builder(
            this,
            notificationChannelId
        ) else Notification.Builder(this)

        return builder
            .setContentTitle("My Service")
            .setContentText("Endless service working...")
            .setContentIntent(pendingIntent)
            .setSmallIcon(R.mipmap.ic_launcher)
            .setTicker("Ticker text")
            .setPriority(Notification.PRIORITY_HIGH) // for under android 26 compatibility
            .build()
    }

    override fun onDestroy() {
        super.onDestroy()
        // Trigger is a separate kotlin class with variables
        if (Trigger.getTrigger() == 1){
            timer.cancel()
            timer.purge()
        }
    }

    private fun showOrderNumber() {
        i += 1
    }

}
© www.soinside.com 2019 - 2024. All rights reserved.