Skip to content

Instantly share code, notes, and snippets.

@Aidanvii7
Last active February 10, 2022 09:44
Show Gist options
  • Save Aidanvii7/f2c93003ed62133d84f4872180dae347 to your computer and use it in GitHub Desktop.
Save Aidanvii7/f2c93003ed62133d84f4872180dae347 to your computer and use it in GitHub Desktop.
Utility for binding a local android service in compose
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(),
)
}
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
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment