我正在研究 MVVM 架构。我想在我的 Android 应用程序中的模块之间共享视图模型的实例。当用户从应用程序模块完成骑行时,我想访问我的聊天模块视图模型实例以执行一些数据库操作,即清除对话实体等。我正在使用带有视图模型的房间数据库。 ChatActivityNew 是聊天模块中的一个 Activity。
App模块预约活动
Dialogs.INSTANCE.showRideStatusDialog(mCurrentActivity, new View.OnClickListener() {
@Override
public void onClick(View v) {
Dialogs.INSTANCE.dismissDialog();
Dialogs.INSTANCE.showLoader(mCurrentActivity);
ChatActivityNew.setMukamalListener(iMukamalCallback);
dataRepository.requestEndRide(mCurrentActivity, driversDataHandler);
}
}
聊天模块ChatActivityNew
/**
* Set the Mukamal Callback listener & call onMukamal abstract
* method which takes Message view model as a parameter.
*
* @param iMukamalCallback is a callback listener.
*/
public static void setMukamalListener(IMukamalCallback iMukamalCallback) {
mukamalCallback = iMukamalCallback;
mukamalCallback.onMukamal(mModel);
}
mModel 为 null,因为 Activity 尚未加载并且 MessageViewModel 为 null,那么我如何访问 MessageViewModel 的实例。
我已经遵循了android开发者文档 https://developer.android.com/topic/libraries/architecture/viewmodel
任何帮助都将非常感激。
编辑
Dialogs.INSTANCE.showRideStatusDialog(mCurrentActivity, new View.OnClickListener() {
@Override
public void onClick(View v) {
Dialogs.INSTANCE.dismissDialog();
Dialogs.INSTANCE.showLoader(mCurrentActivity);
EventBus.getDefault().postSticky(
new MessageEvent(com.example.chatmodule.utils.Constants.RIDE_COMPLETE)
);
dataRepository.requestEndRide(mCurrentActivity, driversDataHandler);
}
}
聊天模块订阅方式
@Subscribe(threadMode = ThreadMode.MAIN, sticky = true)
public void onMessageEvent(MessageEvent event) {
if (mModel != null && event.message.equalsIgnoreCase(RIDE_COMPLETE)){
mModel.deleteConversation();
mModel.deleteMessages();
}
}
理想情况下,您希望尽可能地解耦这些视图模型。为了实现您想要做的事情,您需要一个事件聚合器机制。
在您的示例中,您的聊天模块将订阅“NowSave”类型的事件,并且您的应用程序模块在需要保存数据时将发布“NowSave”类型的事件。
在 Android 世界中,
EventBus
看起来像是用于这种机制的流行库:
http://greenrobot.org/eventbus/
O找到了两种方法来做到这一点
#1 - 将 viewModel 的字段存储在伴随对象中。
这样所有实例都将访问相同的数据 优点
private val sharedViewModel: SharedViewModel by viewModels()
or
private val sharedViewModel: SharedViewModel by activityViewModels()
缺点
#2 - 创建您自己的“ViewModelFactory” 这样您就可以控制它的创建,并作为单个实例提供 优点
缺点
lateinit var sharedViewModelFactory : SharedViewModelFactory
private lateinit var sharedViewModel: SharedViewModel
...
sharedViewModel = ViewModelProvider(this,sharedViewModelFactory).get(SharedViewModel::class.java)
创建工厂的代码如下:
package ...login.data.dependencyInjection
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
...
import dagger.Binds
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.android.components.ActivityComponent
import dagger.hilt.android.scopes.ActivityScoped
import dagger.hilt.components.SingletonComponent
import javax.inject.Inject
import javax.inject.Scope
import javax.inject.Singleton
@Module
@InstallIn(SingletonComponent::class)
class SharedViewModelModule {
@Singleton
@Provides
fun provideViewModelInstanceHolder(): ViewModelInstanceHolder {
return ViewModelInstanceHolder()
}
@Singleton
@Provides
fun provideUserViewModelFactory(
viewModelInstanceHolder: ViewModelInstanceHolder
): SharedViewModelFactory {
return SharedViewModelFactory(
viewModelInstanceHolder
)
}
}
class ViewModelInstanceHolder() {
companion object {
var sharedViewModel: SharedViewModel? = null
}
fun getInstance(): SharedViewModel {
if (sharedViewModel == null) {
sharedViewModel = SharedViewModel()
}
return sharedViewModel!!
}
}
class SharedViewModelFactory @Inject constructor(private val viewModelInstanceHolder: ViewModelInstanceHolder) :
ViewModelProvider.NewInstanceFactory() {
@Suppress("UNCHECKED_CAST")
override fun <T : ViewModel> create(modelClass: Class<T>): T {
return viewModelInstanceHolder.getInstance() as T
}
}