I was using fragment and now I attached ViewModel to it and was transferring code to ViewModel and activity?.packageManager?.getPackageInfo(uri, PackageManager.GET_ACTIVITIES)
this line shows an error. How can I access package manager in ViewModel?
CodePudding user response:
On way is to extend AndroidViewModel
instead of ViewModel
as:
class MyFragmentViewModel(application: Application) : AndroidViewModel(application) {
...
Now you can call:
application.packageManager?.getPackageInfo(uri, PackageManager.GET_ACTIVITIES)
CodePudding user response:
Theoretically if you are implementing MVVM pattern (I see you implementing ViewModel), android.* layer should be handled in the View, Activities/Contexts shouldn't be managed in the ViewModel to avoid Memory Leaks. Even though, depending on the project context, of course this rule doesn't apply to every single project context, I think the best approach would be (if not Dependency Injection is been used) to have an Application Provider.
Create an object:
object ApplicationProvider {
@Volatile
lateinit var application: Application
fun initialize(_application: Application) {
if (!::application.isInitialized) {
synchronized(this) {
application = _application
}
}
}
}
In your MainActivity, initialise the ApplicationProvider as the following:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
ApplicationProvider.initialize(this.application)
}
Now you can access the ApplicationContext in your whole project where is needed with:
ApplicationProvider.application.applicationContext
Remember to not assign ApplicationContext to static fields (as a val e.g.) to avoid Memory Leaks.
PD: I'm not very fan of AndroidViewModel, but I guess it is a good solution as well, as a colleague mentioned before :D