Обработчик () работает медленнее в Сервисе, когда выключен экран - PullRequest
0 голосов
/ 07 марта 2020

Я сделал Сервис, который на самом деле является простым фоновым счетчиком.

Он просто добавляет 1 к последнему номеру и затем переходит к пользовательскому интерфейсу.

Моя предыдущая проблема заключалась в том, что Handler () иногда работал очень медленно, когда смартфон был выключен или если он не заряжается Недавно я обнаружил такую ​​же проблему на этом форуме . Я добавил PowerManager.WakeLock к своему Сервису, и все работало нормально ...

Но я решил протестировать его дольше и запустил приложение одновременно на трех смартфонах и оставил их примерно на полтора часа. Когда я вернулся, я увидел полную разницу между тремя из них.

Первый показывает 5100 (1 ч 25 минут), второй - 2800 (46 минут) и третий - 5660 (1 ч 34 минуты) , Я был почти уверен, что wakelock выполнит эту работу правильно, но теперь я не знаю, что там произошло.

Вот код моей службы:

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" />

1 Ответ

0 голосов
/ 08 марта 2020

Наконец, после различных испытаний я получил самый точный способ сделать простой счетчик. Вместо относительно надежного Handle() метода я бы рекомендовал использовать Timer(). Он работал абсолютно одинаково на всех моих четырех смартфонах. Wakelock также требуется для этого. Я также проверил бы 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
    }

}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...