Search code examples
androidkotlinmvvmviewmodel

Can I share ViewModel inside companion object?


I have a problem with MVVM on Android. I want to share data between the two activities. In one of them, I created ViewModel (MainActivity) and next in a companion object share ViewModel to another activity (SecondActivity). Is it safe? Is exists another recommended way?

Thanks for any help and explanation

    class SecondActivity : AppCompatActivity() {    

    lateinit var viewModelTwo: ViewModelForActivities

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_second)

    }


    override fun onStart() {
        super.onStart()
        viewModelTwo = MainActivity.viewModel
        textViewTwo.setText(viewModelTwo.licznik.toString())

    }
}

class MainActivity : AppCompatActivity() {

    companion object{
        lateinit var viewModel: ViewModelForActivities
    }


    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        viewModel = ViewModelProviders.of(this).get(ViewModelForActivities::class.java)

        textViewOne.setOnClickListener {
            val intent = Intent(applicationContext, SecondActivity::class.java)
            viewModel.licznik++
            startActivity(intent)

        }

    }
}    

The application works correctly but I'm afraid of safeness. Is it the correct way?


Solution

  • Is it safe?

    I feel fairly confident it goes against what the developers of ViewModel have in mind. In particular, bear in mind that a ViewModel is cleared when its LifecycleOwner is destroyed, and so you may run into problems with shared ViewModel objects getting cleared when you would prefer that they not.

    Personally, I would not use this approach.

    Is exists another recommended way?

    Here are three:

    • Have one activity and two fragments, with a shared ViewModel between the fragments. Sharing a ViewModel between fragments is just a matter of using ViewModelProviders.of(requireActivity()) instead of ViewModelProviders.of(this). Or, if you are using the Navigation component, you might use a ViewModel scoped to a particular nav graph.

    • Pass the data between the activities via Intent extras.

    • Have the common data be managed by a repository, passing identifiers between the activities via Intent extras to look up that data in the repository.