Я настраиваю новый 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
но моя деятельность прекращается!
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)
}
}
...
}