是否可以绑定到 android 中可组合项内的服务

Emm*_*Joe 1 android android-jetpack android-jetpack-compose

我正在开发一个 Android 应用程序,当前绑定到我的位置服务,我在活动内部时从中接收位置更新,并且我想在用户完成身份验证过程后从可组合项内部执行此操作

小智 5

我还没有对此进行测试,但请随意尝试,如果需要,它可以适用于公开 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
}
Run Code Online (Sandbox Code Playgroud)

然后:

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(),
    )
}
Run Code Online (Sandbox Code Playgroud)

如果有效,我会更新这个答案。