Android 安卓MVVM。传递具有上下文作为依赖项的对象
我有一个Android 安卓MVVM。传递具有上下文作为依赖项的对象,android,viewmodel,android-mvvm,Android,Viewmodel,Android Mvvm,我有一个viewmodel,它接受model作为构造函数参数之一MainModel具有context(我需要它来注册broadcastReceiver) 我知道viewmodel的不应该引用上下文。那么这种方法正确吗? 或者所有需要上下文的东西,比如位置接收器、广播接收器。。。是否应在视图aka活动级别处理?然后将结果传递给viewmodel 编辑 我还将添加另一个示例,我有PermissionManager,该示例具有请求某种权限的活动。我想将该管理器用于我所有的视图模型在我的视图模型中使用某
viewmodel
,它接受model作为构造函数参数之一MainModel
具有context
(我需要它来注册broadcastReceiver
)
我知道viewmodel的
不应该引用上下文
。那么这种方法正确吗?
或者所有需要上下文的东西,比如位置接收器、广播接收器。。。是否应在视图
aka活动
级别处理?然后将结果传递给viewmodel
编辑
我还将添加另一个示例,我有PermissionManager
,该示例具有请求某种权限的活动。我想将该管理器用于我所有的视图模型
在我的视图模型
中使用某种具有活动
作为参数的管理器是否是个好主意?。我知道直接将上下文
、活动
或视图
传递到我的视图模型
是不好的。但是,在我的视图模型中有其他具有上下文
或活动
(如PermissionManager
)的对象好吗
class MainViewModel(private val permissionManager: PermissionManager) : ViewModel() {
fun doSomethingWithLocation() {
permissionManager.requestLocationPermission({
// do something if permission granted
})
}
fun doSomethingWithCamera() {
permissionManager.requestCameraPermission({
// do something if permission granted
})
}
}
class DetailViewModel(private val permissionManager: PermissionManager) : ViewModel() {
fun doSomethingWithLocation() {
permissionManager.requestLocationPermission({
// do something if permission granted
})
}
fun doSomethingWithCamera() {
permissionManager.requestCameraPermission({
// do something if permission granted
})
}
}
class PermissionManager(activity: Activity) {
private val activityWeakRef = WeakReference(activity)
fun requestLocationPermission(onPermissionGranted: ((Boolean) -> Unit)) {
//
// Location permission implemetntation
//
}
fun requestStoragePermission(onPermissionGranted: ((Boolean) -> Unit)) {
//
// Storage permission implemetntation
//
}
fun requestCameraPermission(onPermissionGranted: ((Boolean) -> Unit)) {
//
// Camera permission implemetntation
//
}
}
尽管您的用例并不完全明显,但我认为如果您的用户触发了某个事件,您需要调用此类的函数。
鉴于这种情况,我建议如下:
<data>
<variable
name="receiverHandler"
type="your.package.MyTestReiverHandler" />
<variable
name="viewModel"
type="your.package.MainViewModel"/>
</data>
这将允许您将此receiverHandler传递到viewModel的函数中
<View
android:onClick="@{viewModel.doSomething(receiverHandler)}" />
创建绑定时,实例化ReceiverHandler并注入它。
构建此布局文件后,绑定中将使用
的字段名
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
val binding = DataBindingUtil.inflate<MainFragmentBinding>(inflater, R.layout.fragment_main, container, false)
binding.viewModel = viewModel
binding.lifecycleOwner = this
binding.receiverHandler = MyTestReiverHandler(container?.context?.applicationContext!!)
override fun onCreateView(充气机:布局充气机,容器:ViewGroup?,savedInstanceState:Bundle?):视图?{
val绑定=数据绑定直到充气(充气机,右布局,主容器,假)
binding.viewModel=viewModel
binding.lifecycleOwner=此
binding.receiverHandler=MyTestReiverHandler(容器?.context?.applicationContext!!)
如果需要通过观察viewModel的属性来调用函数,则不需要将其注入viewModel,因此我对用户交互的假设是这样的
注意:如果要调用此特定类的函数,则layout.xml中的
层次结构中的任何
都是必需的
您可以从AndroidViewModel(应用程序:应用程序)而不是ViewModel扩展MainViewModel。
现在,您可以像以前一样使用您的MainViewModel,并且应用程序实例可用于注册您的broadcastReceiver
class MainViewModel(application: Application) : AndroidViewModel(application) {
}
在活动/片段中
val viewModel = ViewModelProviders.of(this).get(MainViewModel::class.java)
这是正确和容易的一个
所有需要上下文的东西,比如位置接收器、广播接收器……都应该在活动级别的视图中处理吗
不是所有的。我曾经在一个跟踪用户位置的应用程序上工作。因为该应用程序需要跟踪用户位置很长一段时间,而其他操作同时工作。我决定在另一个线程中这样做,并让ViewModel分别广播结果。存储库还需要上下文来构建房间数据库。ViewModel将需要上下文来实例化存储库。这就是为什么我们有AndroidViewModel而不是ViewModel的原因。如果您希望实现依赖项注入以避免这种依赖项,谢谢您的回答!因此,如果我使用Dagger,例如,就没有必要使用AndroidViewModel
,我可以简单地使用ViewModel
?并传递所有必要的对象(如PermissionManager
)对于我的viewmodel
?是的,如果你使用Dagger,你可以简单地使用viewmodel。一个问题!如果你需要检查权限,为什么不直接在活动中执行此操作?如果授予权限,让viewmodel执行。我希望有一个地方拥有我的应用程序的所有必要权限。对我来说,我使用了静态方法。我不确定这是不是最好的做法,但我很满意
val viewModel = ViewModelProviders.of(this).get(MainViewModel::class.java)