skip to Main Content

When the button is clicked, data is received from the API, after which the Observer is fired, however, even with removeObservers, it is called twice.
Without removeObservers it triggers more than 2 times.

MainActivity

class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)

    setContent {
        TestApiAppTheme {
            Surface() {
                TextInfo()
            }
        }
    }
}

@Preview
@Composable
fun TextInfo() {

    val viewModel = ViewModelProvider(this).get(MainViewModel::class.java)

    var txt = remember {
        mutableStateOf(0)
    }

    viewModel.serverInfoResponse.removeObservers(this)
    viewModel.serverInfoResponse.observe(this) {
        txt.value = it.players
        Toast.makeText(this, "${it.players} -", Toast.LENGTH_SHORT).show()
    }

    Column() {
        Text(
            text = txt.value.toString(),
        )

        Button(onClick = {
            viewModel.getServerInfo()
            visible = true
        }) {
            Text("Update")
        }
    }
}}

ViewModel

var serverInfoResponse = MutableLiveData<ServerInfo>()

fun getServerInfo() {
    viewModelScope.launch {
        val apiService = ApiService.getInstance()

        val info = apiService.getInfo()
        serverInfoResponse.value = info
    }
}

2

Answers


  1. Composable functions can get called many times although the compiler tries to reduce how often.

    You should not have side effects in them such as adding and removing the observer. Since LiveData sends the last item out to new subscribers, every time this function composes you get the value again.

    The correct way to consume live data is to convert it to a state. https://developer.android.com/reference/kotlin/androidx/compose/runtime/livedata/package-summary

    But then you still have problems with showing the toast too often. For that you will need something like a LaunchEffect to make sure you only show a toast once. Might want to consider if you really need a toast or if a compose type UI would be better.

    Login or Signup to reply.
  2. A composable function can be called multiple times, whenever the it observes changes removeObserver() and observe() should not be called directly but, rather in some effect.

    The extension function observeAsState() does all work to subscribe and correctly unsubscribe for you.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search