如何绑定到LocalService并调用不带按钮的getRandomNumber()?

时间:2019-04-07 01:46:08

标签: android kotlin

我正在使用此方法LocalService设置一个新的getRandomNumber(),并且当此活动绑定到没有按钮的服务时,想从BindingActivity自动调用它。在用户开始使用getRandomNumber()之前如何呼叫BindingActivity

当我在getRandomNumber()onCreateonStart中使用onResume方法时。我收到错误消息,我认为因为该方法在活动绑定到LocalService之前会先获得调用!

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 但是我的活动停止了!

1 个答案:

答案 0 :(得分:0)

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

    ...
}