Home > Enterprise >  How to make sure I use the same instance of the ViewModel?
How to make sure I use the same instance of the ViewModel?

Time:12-21

In the MainActivity I create a ViewModel object using:

class MainActivity : ComponentActivity() {
    private val viewModel by viewModels<MainViewModel>()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            if(viewModel.isActive()) {
                //Do stuff...
            } else {
                //Do other stuff...
            }
        }
    }
}

And inside a composable function, I'm injecting it using Hilt:

@Composable
fun ActivateScreen(
    viewModel: MainViewModel = hiltViewModel()
) {
    Scaffold(
        topBar = { /... },
        content = {
            UiContent(
                onClick = {
                    viewModel.activate()
                }
            )
        }
    )
}

But it seems to me that the view model objects are different objects, because when I click activate, the change is not propagated to the MainActivity. I need to restart the app in order to see the change. How to make sure I'm using the same instance? Any help would be greatly appreciated.

CodePudding user response:

A quick way to see that is not the same is to place a breakpoint in the init block of the viewmodel, if the call inside mainactivity executes it and the call inside your composable does it , that will tell you that the two instances are different. If you are already creating the viewmodel in your activity with hilt, just pass it as a parameter to your composable

class MainActivity : ComponentActivity() {
    private val viewModel by viewModels<MainViewModel>()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            if(viewModel.isActive()) {
                //Do stuff...
              ActivateScreen(viewmodel)
            } else {
                //Do other stuff...
            }
        }
    }
}

@Composable
fun ActivateScreen(
    viewModel: MainViewModel
) {
    Scaffold(
        topBar = { /... },
        content = {
            UiContent(
                onClick = {
                    viewModel.activate()
                }
            )
        }
    )
}

CodePudding user response:

If you want to use Dagger Hilt you should do like this: (I also used a similar code in my project)

@AndroidEntryPoint
class MainActivity : ComponentActivity() {
@Inject
lateinit var viewModel: MainViewModel

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContent {
        if(viewModel.isActive()) {
            //Do stuff...
          ActivateScreen(viewmodel)
        } else {
            //Do other stuff...
        }
    }
}

}

@Composable
fun ActivateScreen(
viewModel: MainViewModel
) {
Scaffold(
    topBar = { /... },
    content = {
        UiContent(
            onClick = {
                viewModel.activate()
            }
        )
    }
)

}

@HiltAndroidApp
class MyApp: Application()

And in Manifest.xml

<application
    android:name=".MyApp"
  • Related