Vitaliy Zarubin

    Vitaliy Zarubin

    1 year ago
    It's good way?Dao Room
    @Query("SELECT * FROM ModelRepo WHERE id = :id")
    fun getModel(id: Long): Flow<ModelRepo>
    ViewModel
    val findByIdRepo: (Long) -> Flow<ModelRepo?> = { id -> dataRepo.getModel(id).distinctUntilChanged() }
    @Composable
    val model: ModelRepo? by viewModel.findByIdRepo(repoId).collectAsState(initial = null)
    n

    nitrog42

    1 year ago
    I will just say that
    val findByIdRepo: (Long) -> Flow<ModelRepo?> = { id -> dataRepo.getModel(id).distinctUntilChanged() }
    should probably just be a method :
    fun findByIdRepo(id: Long): Flow<ModelRepo?> = dataRepo.getModel(id).distinctUntilChanged()
    Vitaliy Zarubin

    Vitaliy Zarubin

    1 year ago
    Adam Powell

    Adam Powell

    1 year ago
    The
    @Composable
    code has a bug here:
    viewModel.findByIdRepo
    is returning a new
    Flow
    instance on each call. If
    .collectAsState
    has a new
    Flow
    instance to collect on a recomposition, it will cancel the old collection and start a new one fresh. This would cancel and re-start a lot of data loads if this function recomposes frequently.
    You can solve this by remembering the flow you use unless the viewModel or the repoId change:
    val model by remember(viewModel, repoId) {
      viewModel.findByIdRepo(repo)
    }.collectAsState(null)
    additionally it seems a little silly to use a function val for
    findByIdRepo
    instead of a normal function there, but that won't affect correctness, just add a little overhead
    Vitaliy Zarubin

    Vitaliy Zarubin

    1 year ago
    little silly
    Why? Isn't it the same thing?
    Adam Powell

    Adam Powell

    1 year ago
    Check
    View Kotlin bytecode
    on each approach in the IDE 🙂
    for most situations on android (combinations of kotlin compiler, d8 desugaring of openjdk8 language features, the specific device OS version) the val + lambda version ends up creating a separate object with an
    invoke()
    method as opposed to a plain final function call
    Vitaliy Zarubin

    Vitaliy Zarubin

    1 year ago
    I think this is it. But how is this to be understood? How to learn to understand bytecode? 🙂
    Adam Powell

    Adam Powell

    1 year ago
    If you hit that "Decompile" button at the top it'll show something more java-like. Note that it's created a getter for a function object
    you'll also want to look at the difference between the code that calls this function
    Vitaliy Zarubin

    Vitaliy Zarubin

    1 year ago
    Got it. Thank you.