Closed vivekwolf123 closed 3 years ago
ViewModel
instances are meant to survive configuration changes, screen rotation for e.g. This is the default behaviour.
Could try printing the ViewModel
object to logcat and see the hash are the same before and after rotation?
Log.d(TAG, homeViewModel);
in onCreateView
.
Yes I printed out as you suggested and the hashes are same before and after rotation. I inject the viewModel in my fragment HomeFragment
as -
private val homeViewModel: HomeViewModel by viewModel { parametersOf( Bundle(), "homeViewModel" ) }
Basically HomeFragment
is a login screen where I enter email and password and I hit login button to make a login API request. In the middle of the API request, I rotate the screen and the progress dialog is gone and the login view stays although API request succeeds after a while. When I rotate back to portrait mode, the login view is still displayed.
I expect that the instance of viewModel should still observe the changes since it has survived the configuration changes but it doesn't seem to.
Could it be that you're starting Koin in MainActivity rather than MainApplication? MainActivity gets destroyed on screen rotation, which would destroy Koin, no?
No I start in MainApplication onCreate()
only -
startKoin {
androidContext(this@MyApp)
modules(AppModules.appModules)
}
For observing the results correctly use the viewLifecycleOwner:
homeViewModel.showResults().observe(viewLifecycleOwner, Observer { .... })
This may not solve your problem but whenever you need to use the events to update UI use viewLifecycleOwner
I used to have this issue with a similar approach, I had a couple of fragments and a navigation drawer and each time I had a configuration change when the views are reconstructed my fragments would somehow get a new instance of their viewmodel/s
, which didn't seem right, considering this lifecycle diagram, but I guess this is true for activities but not fragments?
What I had to do was to use tags/ids in my supportFragmentManager
when I commit
and upon getting navigation item change I would call supportFragmentManager.findFragmentByTag
and do a null check on the result, if it is null I'll create a new instance of my fragment.
Additionally I also use retainInstance
on my fragments, the difference in lifecycle handling are as follows: Complete lifecycle
Hope this helps you :wink:
You must validate the status in the onActivityCreated
if (savedInstanceState == null) YourviewModel.event()
I tried 2 things... neither of them works.
onCreate()
and unload it in onDestroy()
The init { }
block of ViewModel gets called when I change the orientation of the screen from portrait to landscape
However, the same doesn't happen if I use,
val viewModel = ViewModelProvider(this).get(MainViewModel::class.java)
When I use ViewModelProvider
, init { }
block gets called only once. So, it survives orientation change
onCreate()
and onDestroy()
respectively.So, I added this module in Application class. ViewModel still doesn't survive orientation change.
Either I am missing something or Koin still doesn't support this.
Ideally, I should be able to load and unload in onCreate()
and onDestroy()
of an Activity respectively & ViewModel should still survive orientation change
@arnaudgiuliani Is this issue resolved ?
I tried and found out two interesting things:
if you are using val vm: MyViewModel by inject()
, the viewModel can't survive config change.
But if you use:
import org.koin.androidx.viewmodel.ext.android.viewModel
class MyActivity : AppCompatActivity() {
val vm: MyViewModel by viewModel()
Now the viewModel could survive config change
Describe the bug I am using -
implementation "org.koin:koin-androidx-viewmodel:2.1.0-alpha-3"
In my modules, I declare it as -
private val viewModels = module { viewModel { (handle: SavedStateHandle) -> HomeViewModel(handle, get()) } }
I create my
HomeFragment
insideonCreate()
ofMainActivity
whensavedInstanceState == null
.In my
HomeFragment
I inject my viewModel like this -private val homeViewModel: HomeViewModel by viewModel { parametersOf( Bundle(), "homeViewModel" ) }
And in
HomeFragment
, insideonViewCreated()
I observe the changes in livedata -homeViewModel.showResults().observe(this, Observer { .... })
When the screen is rotated to landscape, the
onCreate()
ofMainActivity
is called again and the fragment is newly created and the viewModel instance in the fragment is gone.Is it not possible for the viewmodel instance to be retained even after screen rotation change?