Long running background task from BroadcastReceiver - which class to use?

950 views Asked by At

Since AsyncTask, IntentSerrvice and JobIntentService are all deprecated, which tool or class should I go for in 2022?

I want to re-schedule alarms in a BroadcastReceiver after a device rebooted (since alarms get lost in the process). The task will most probably take < 1 min to finish. I just need the safety of it completing and not being killed off by the system.


The documentation on Broadcasts shows an (outdated) example with goAsync() and the deprecated AsyncTask.
But it also mentions JobService. Is that the replacement? What about WorkManager?

1

There are 1 answers

4
baka3k On BEST ANSWER

goAsync() return a PendingIntent - it mean you ask for android system extend time life of Broadcast receiver => goAsync() is used for short background task. Life time of BroadcastReceiver is very short, so... for long time background task, you must to change to other context has longer life time, such as: Service, JobService..etc. Example:

  1. BroadcastReceiver received intent
  2. BroadcastReceiver start a service, run worker thread to process long time task
  3. after worker thread finish, call finish service too

=========================================

class MyIntentService : Service() {
    private val handleThread = HandlerThread("MyThread")
    private lateinit var workerHandler: Handler
    override fun onCreate() {
        super.onCreate()
        handleThread.start()
        workerHandler = Handler(handleThread.looper)
    }

    override fun onDestroy() {
        workerHandler.removeCallbacksAndMessages(null)
        handleThread.quitSafely()
        super.onDestroy()
    }
    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
        val data = intent?.data
        workerTask(data)
        return START_NOT_STICKY
    }

    private fun workerTask(data: Uri?) {
        workerHandler.post {
            heavyTask(data)
            finishMyIntentService()
        }
    }

    private fun finishMyIntentService() {
        stopSelf()
    }

    private fun heavyTask(data: Uri?) {
        // to do heavyTask example
        for (i in 1..20)
        {
            Log.d("test","#heavyTask() $i")
            Thread.sleep(1000)
        }
    }

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

then startService from BroadCastReceiver