Disable service restart on button click

让人想犯罪 __ 提交于 2020-12-16 02:30:20

问题


I start a foreground service that downloads a file when users click on a button. What happens now is when I click again on the button, the thread inside service starts second time and I see in a notification that progress is updated for both threads (jumps presentae between threads).

How can I prevent starting the second thread in case the first one is running, how can I prevent startService() or onStartCommand() is being called if the service is still running?

class ForegroundService : Service() {
    private val CHANNEL_ID = "ForegroundService Kotlin"

    companion object {

        fun startService(context: Context, message: String) {
            val startIntent = Intent(context, ForegroundService::class.java)
            startIntent.putExtra("inputExtra", message)
            ContextCompat.startForegroundService(context, startIntent)
        }

        fun stopService(context: Context) {
            val stopIntent = Intent(context, ForegroundService::class.java)
            context.stopService(stopIntent)
        }
    }

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


        val input = intent?.getStringExtra("inputExtra")
        createNotificationChannel()
        val notificationIntent = Intent(this, MainActivity::class.java)
        val pendingIntent = PendingIntent.getActivity(
            this,
            0, notificationIntent, 0
        )

        //start doing some work and update the notification
        //when done calling stopSelf();

        val notification = NotificationCompat.Builder(this, CHANNEL_ID)
            .setContentTitle("Foreground Service Kotlin Example")
            .setContentText(input)
            .setSmallIcon(R.mipmap.ic_launcher)
            .setContentIntent(pendingIntent)
            .build()

        startForeground(1, notification)

        return START_NOT_STICKY
    }

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

    private fun createNotificationChannel() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            val serviceChannel = NotificationChannel(
                CHANNEL_ID, "Foreground Service Channel",
                NotificationManager.IMPORTANCE_DEFAULT
            )

            val manager = getSystemService(NotificationManager::class.java)
            manager!!.createNotificationChannel(serviceChannel)
        }
    }
}

Calling

buttonGoNext.setOnClickListener {
    val intent = Intent(this, DownloadActivity::class.java)
    startActivity(intent)
}

回答1:


In your startService function you want to check if this service is already running. If the service is already running, you could just early return. There is multiple SO threads already regarding the problem of how to find out if a service is already running.

To have a little more control over your background work, I would suggest you familiarize yourself with Android's WorkManager. You could create a unique OneTimeWorkRequest with a KEEP policy, that would solve the problem as well.

Also, you should seperate your responsibilities in your code a little better. Your ForegroundService class currently takes care of too many things at once. You create notification channels, show notifications and probably also want to take care of the behaviour you described. It is generally good practice to seperate those concerns and move them to different classes. This also makes it more testable.



来源:https://stackoverflow.com/questions/65170630/disable-service-restart-on-button-click

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!