Как привязать к LocalService и вызвать getRandomNumber() без кнопки?

Я настраиваю новый LocalService с помощью этого метода getRandomNumber() и хочу автоматически вызывать его из BindingActivity, когда это действие привязывается к службе без кнопки. Как я могу вызвать getRandomNumber() до того, как пользователь начнет использовать BindingActivity?

Когда я использую метод getRandomNumber() внутри onCreate, onStart или onResume. Я получаю сообщение об ошибке, я думаю, потому что метод получает вызовы до того, как активность привязывается к LocalService!

Код локальной службы:

class LocalService : Service() {
    // Binder given to clients
    private val binder = LocalBinder()

    // Random number generator
    private val mGenerator = Random()

    /** method for clients  */
    val randomNumber: Int
        get() = mGenerator.nextInt(100)

    /**
     * Class used for the client Binder.  Because we know this service always
     * runs in the same process as its clients, we don't need to deal with IPC.
     */
    inner class LocalBinder : Binder() {
        // Return this instance of LocalService so clients can call public methods
        fun getService(): LocalService = this@LocalService
    }

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

Код BindingActivity:

class BindingActivity : Activity() {
    private lateinit var mService: LocalService
    private var mBound: Boolean = false

    /** Defines callbacks for service binding, passed to bindService()  */
    private val connection = object : ServiceConnection {

        override fun onServiceConnected(className: ComponentName, service: IBinder) {
            // We've bound to LocalService, cast the IBinder and get LocalService instance
            val binder = service as LocalService.LocalBinder
            mService = binder.getService()
            mBound = true
        }

        override fun onServiceDisconnected(arg0: ComponentName) {
            mBound = false
        }
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.main)
    }

    override fun onStart() {
        super.onStart()
        // Bind to LocalService
        Intent(this, LocalService::class.java).also { intent ->
            bindService(intent, connection, Context.BIND_AUTO_CREATE)
        }

        // PROBLEM
        val num: Int = mService.randomNumber
        Toast.makeText(this, "number: $num", Toast.LENGTH_SHORT).show()
    }

    override fun onStop() {
        super.onStop()
        unbindService(connection)
        mBound = false
    }
}

От кого: https://developer.android.com/guide/components/bound-services#Binder

Я ожидаю, что эта строка будет работать внутри метода onStart: val num: Int = mService.randomNumber но моя деятельность прекращается!

0
0
89
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

bindService является асинхронным. Вот почему у вас есть обратный вызов с onServiceConnected().

Чтобы получить доступ к услуге, вам нужно дождаться звонка onServiceConnected(). В этом тривиальном примере я бы просто поместил эти строки под // PROBLEM внизу onServiceConnected().

class BindingActivity : Activity() {
    private lateinit var mService: LocalService
    private var mBound: Boolean = false

    /** Defines callbacks for service binding, passed to bindService()  */
    private val connection = object : ServiceConnection {

        override fun onServiceConnected(className: ComponentName, service: IBinder) {
            // We've bound to LocalService, cast the IBinder and get LocalService instance
            val binder = service as LocalService.LocalBinder
            mService = binder.getService()
            mBound = true

            val num: Int = mService.randomNumber
            Toast.makeText(this, "number: $num", Toast.LENGTH_SHORT).show()
        }

        override fun onServiceDisconnected(arg0: ComponentName) {
            mBound = false
        }
    }

    ...

    override fun onStart() {
        super.onStart()
        // Bind to LocalService
        Intent(this, LocalService::class.java).also { intent ->
            bindService(intent, connection, Context.BIND_AUTO_CREATE)
        } 
    }

    ...
}

Другие вопросы по теме