Is force recompose is good idea or not in jetpack compose

Issue

I don’t understand to force recompose is actually a good idea or not. I cannot find a way to solve the problem. I have value of mutableStateOf it’s type of Boolean and I am calling a function onResume to check that Boolean value in my viewmodel.

BloodPressurePairViewModel.kt

class BloodPressurePairViewModel : BaseViewModel() {
   
    var isBluetoothEnabled by mutableStateOf(false)
        private set
   
    fun setBluetoothEnable(newValue: Boolean) {
        isBluetoothEnabled = newValue
    }

    fun handleBluetoothScanState(bluetoothAdapter: BluetoothAdapter) {
        if (isBluetoothEnabled) {
            getPairedDevice(bluetoothAdapter)
            startScan(bluetoothAdapter)
        } else {
            cancelTimeWarning()
            stopScan(bluetoothAdapter)
        }
    }

     fun cancelTimeWarning() {
        // more logic here
    }

    // more function here I am not adding.

}

BluetoothConnectionContentStateful

fun BluetoothConnectionContentStateful(
    context: Context = LocalContext.current,
    viewModel: BloodPressurePairViewModel = getViewModel(),
) {
    val activity = context as ComponentActivity
    val rememberPairScreenState = rememberConnectionScreenState(context, viewModel)

    DisposableEffect(key1 = lifecycleOwner) {
          val lifeCycleEventObserver = LifecycleEventObserver { _, event ->
            when (event) {
                Lifecycle.Event.ON_RESUME -> {
viewModel.handleBluetoothScanState(rememberPairScreenState.bluetoothAdapter)
                            rememberPairScreenState.bluetoothStatusRegister.apply {
                                   context.registerReceiver(this,IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED))
                        },
                        Lifecycle.Event.ON_PAUSE -> {
                            rememberPairScreenState.unRegisterBluetoothStatusReceiver()
                        }
                        else -> {}
                    }
                }
                lifecycleOwner.lifecycle.addObserver(lifeCycleEventObserver)
                onDispose {
                    lifecycleOwner.lifecycle.removeObserver(lifeCycleEventObserver)
                }
            }

rememberConnectionScreenState

@Composable
fun rememberConnectionScreenState(context: Context, viewModel: BloodPressurePairViewModel) = remember {
    ConnectionScreenState(context, viewModel)
}

class ConnectionScreenState(context: Context, private val viewModel: BloodPressurePairViewModel) {
    private val bluetoothManager: BluetoothManager by lazy { activity.getSystemService(BluetoothManager::class.java) }
    val bluetoothAdapter: BluetoothAdapter by lazy { bluetoothManager.adapter }
    var bluetoothStatusRegister = object : BroadcastReceiver() {
        override fun onReceive(context: Context?, intent: Intent?) {
            if (intent?.action == BluetoothAdapter.ACTION_STATE_CHANGED) {
                when (intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR)) {
                    BluetoothAdapter.STATE_OFF -> viewModel.setBluetoothEnable(false)
                    BluetoothAdapter.STATE_ON -> viewModel.setBluetoothEnable(true)
                }
            }
        }
    }

    fun unRegisterBluetoothStatusReceiver() {
        activity.unregisterReceiver(bluetoothStatusRegister)
    }
}

When bluetoothStatusRegister is trigger and BluetoothAdapter.STATE_OFF is true and then I called viewModel.setBluetoothEnable(false) the isBluetoothEnabled is false. Then I don’t understand how to recall the function of handleBluetoothScanState(bluetoothAdapter). So is this good idea to recompose the function? Thanks

Solution

Generally it is not what you want to do. Especially because your recomposition can lead to recompositions of another composables which you don’t need. In addition, as z.y. mentioned, this can lead to exception.

What you should do is to tie your recomposition to bluetooth state, which you will save in your ViewModel. Then you can use LaunchedEffect to invoke some actions on state change.

val bluetoothState by remember { mutableStateOf (viewModel.bluetoothState) } 
// Please note that design of type you want your state to be is up to you
LaunchedEffect(bluetoothState) {
    // Perform any manipulation you want on bluetooth state change
}

Answered By – Steyrix

Answer Checked By – Terry (FlutterFixes Volunteer)

Leave a Reply

Your email address will not be published. Required fields are marked *