Функция принудительной остановки l oop в IntentService - PullRequest
0 голосов
/ 12 февраля 2020

В моем сервисе намерений есть функция, которая работает как обратный отсчет. Он называется counter.

Что следует добавить в IntentService или непосредственно в counter, чтобы остановить l oop после некоторого действия в MainActivity?

class IntentServiceExample : IntentService("Loop_test") {
    private val CHANNEL_ID = "ForegroundService Kotlin"

    companion object {
        val PARAM_OUT_MSG = "None"
    }

    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)
        }
    }

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

        val notificationIntent = Intent(this, MainActivity::class.java)
        val pendingIntent = PendingIntent.getActivity(
            this,
            0, notificationIntent, 0
        )
        val notification = NotificationCompat.Builder(this, CHANNEL_ID)
            .setContentTitle("Foreground Service Kotlin Example")
            .setContentText("kylsha")
            .setSmallIcon(R.drawable.ic_notification)
            .setContentIntent(pendingIntent)
            .build()

        startForeground(1, notification)

        return super.onStartCommand(intent, flags, startId)
    }

    override fun onHandleIntent(p0: Intent?) {
        Toast.makeText(this,"Service started",Toast.LENGTH_LONG).show()

        val broadcastIntent = Intent()
        broadcastIntent.action = "com.example.intenttest.action.RESPONSE"
        broadcastIntent.addCategory(Intent.CATEGORY_DEFAULT)
        sendBroadcast(broadcastIntent)
        counter(broadcastIntent)
    }

    fun counter(bc: Intent){
        for (i in 1..100){
            bc.putExtra(PARAM_OUT_MSG, i.toString())
            Thread.sleep(1000)
            d("number", i.toString())
            sendBroadcast(bc)
        }
    }

    override fun onDestroy() {
        super.onDestroy()
        stopSelf()

    }
}

Ответы [ 2 ]

1 голос
/ 12 февраля 2020

создать переменную в классе. Создайте установщик для установки переменной true. В вашей подпрограмме rcounter проверьте, установлена ​​ли переменная.

private val cancelCounter = false
public fun setToCancel() {
    cancelCounter = true
}

/*Stuff*/

fun counter(bc: Intent){
    for (i in 1..100){
        if (cancelCounter) {
            cancelCounter = false
            break
        }
        bc.putExtra(PARAM_OUT_MSG, i.toString())
        Thread.sleep(1000)
        d("number", i.toString())
        sendBroadcast(bc)
    }
}

У вас может не быть прямого доступа к объекту из main - если нет, то вы должны создать этот класс с одноэлементным шаблоном;)

Я не кодирую в kotlin достаточно, чтобы теперь «правильный путь» это сделал, но некоторые ссылки на правильный путь: https://blog.mindorks.com/how-to-create-a-singleton-class-in-kotlin https://medium.com/swlh/singleton-class-in-kotlin-c3398e7fd76b

Обе эти ссылки содержат некоторую информацию о том, почему они принимают решения, которые они принимают в шаблоне структуры, а также о том, как работает код для реализаций;)

0 голосов
/ 13 февраля 2020

Для тех, кто также изучает Kotlin Я также опубликую свое решение. Это выглядит довольно просто, однако, возможно, могло бы быть больше решений.

Я создал простой Kotlin объект, подобный:

object Trigger {
    var triggerStop = 0
    fun getTrigger(): Int{
        return triggerStop
    }
}

Как видите, переменная triggerStop может быть изменена и вызывается с функцией getTrigger()

Поэтому я добавил этот объект в MainActivity для кнопок setOnClickListeners:

class MainActivity : AppCompatActivity() {
    lateinit var i:Intent
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        i = Intent(this, IntentServiceExample::class.java)

        buttonStart.setOnClickListener{
            Trigger.triggerStop = 0 // this variable will be checked in IntentService
            startService(i)
        }
        buttonEnd.setOnClickListener{
            Trigger.triggerStop = 1 // this variable will be checked in IntentService
            stopService(i)
        }
    }
}

Затем я поместил этот объект в свой IntentService. В oop о том, что я хочу остановить взаимодействие с пользователем, я поставил галочку, как в ответе @ Watachiaieto.

fun counter(bc: Intent){
    for (i in 1..100){
        val stopIt = Trigger.getTrigger() // get trigger value
        if (stopIt == 1) {
            break
        }
        bc.putExtra(PARAM_OUT_MSG, i.toString())
        Thread.sleep(1000)
        sendBroadcast(bc)
    }
}
...