是否可以在 android 中绑定到可组合项内的服务
Is it possible to bind to a service inside a composable in android
我正在开发一个 android 应用程序,目前绑定到我的位置服务,我在 activity 中从该服务接收位置更新,我想在用户已完成身份验证过程
我还没有对此进行测试,但请随意尝试,如果需要,它可以适用于公开 Messenger 的远程服务。无论如何,这是要点:
package com.example.app
import android.app.Service
import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.content.ServiceConnection
import android.os.Binder
import android.os.IBinder
import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisallowComposableCalls
import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.platform.LocalContext
@Composable
inline fun <reified BoundService : Service, reified BoundServiceBinder : Binder> rememberBoundLocalService(
crossinline getService: @DisallowComposableCalls BoundServiceBinder.() -> BoundService,
): BoundService? {
val context: Context = LocalContext.current
var boundService: BoundService? by remember(context) { mutableStateOf(null) }
val serviceConnection: ServiceConnection = remember(context) {
object : ServiceConnection {
override fun onServiceConnected(className: ComponentName, service: IBinder) {
boundService = (service as BoundServiceBinder).getService()
}
override fun onServiceDisconnected(arg0: ComponentName) {
boundService = null
}
}
}
DisposableEffect(context, serviceConnection) {
context.bindService(Intent(context, BoundService::class.java), serviceConnection, Context.BIND_AUTO_CREATE)
onDispose { context.unbindService(serviceConnection) }
}
return boundService
}
然后:
package com.example.app
import android.app.Service
import android.content.Intent
import android.os.Binder
import android.os.IBinder
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import kotlin.random.Random
class RandomNumberService : Service() {
private val binder = LocalBinder()
private val randomNumberGenerator = Random(seed = 100)
val randomNumber: Int
get() = randomNumberGenerator.nextInt()
inner class LocalBinder : Binder() {
val service: RandomNumberService
get() = this@RandomNumberService
}
override fun onBind(intent: Intent): IBinder = binder
}
@Composable
fun RandomNumberServiceExample() {
val randomNumberService = rememberBoundLocalService<RandomNumberService, RandomNumberService.LocalBinder> { service }
Text(
text = randomNumberService?.randomNumber?.toString().orEmpty(),
)
}
如果可行,我会更新此答案。
我正在开发一个 android 应用程序,目前绑定到我的位置服务,我在 activity 中从该服务接收位置更新,我想在用户已完成身份验证过程
我还没有对此进行测试,但请随意尝试,如果需要,它可以适用于公开 Messenger 的远程服务。无论如何,这是要点:
package com.example.app
import android.app.Service
import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.content.ServiceConnection
import android.os.Binder
import android.os.IBinder
import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisallowComposableCalls
import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.platform.LocalContext
@Composable
inline fun <reified BoundService : Service, reified BoundServiceBinder : Binder> rememberBoundLocalService(
crossinline getService: @DisallowComposableCalls BoundServiceBinder.() -> BoundService,
): BoundService? {
val context: Context = LocalContext.current
var boundService: BoundService? by remember(context) { mutableStateOf(null) }
val serviceConnection: ServiceConnection = remember(context) {
object : ServiceConnection {
override fun onServiceConnected(className: ComponentName, service: IBinder) {
boundService = (service as BoundServiceBinder).getService()
}
override fun onServiceDisconnected(arg0: ComponentName) {
boundService = null
}
}
}
DisposableEffect(context, serviceConnection) {
context.bindService(Intent(context, BoundService::class.java), serviceConnection, Context.BIND_AUTO_CREATE)
onDispose { context.unbindService(serviceConnection) }
}
return boundService
}
然后:
package com.example.app
import android.app.Service
import android.content.Intent
import android.os.Binder
import android.os.IBinder
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import kotlin.random.Random
class RandomNumberService : Service() {
private val binder = LocalBinder()
private val randomNumberGenerator = Random(seed = 100)
val randomNumber: Int
get() = randomNumberGenerator.nextInt()
inner class LocalBinder : Binder() {
val service: RandomNumberService
get() = this@RandomNumberService
}
override fun onBind(intent: Intent): IBinder = binder
}
@Composable
fun RandomNumberServiceExample() {
val randomNumberService = rememberBoundLocalService<RandomNumberService, RandomNumberService.LocalBinder> { service }
Text(
text = randomNumberService?.randomNumber?.toString().orEmpty(),
)
}
如果可行,我会更新此答案。