- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
this 可能重复
我正在使用 dagger2 探索 android 注入(inject) api。所以,在我的示例应用程序中,我直接在 Activity 中注入(inject)了 ViewModel
;看看下面的代码 fragment 。
class SampleApp : Application(), HasActivityInjector {
@Inject
lateinit var dispatchingAndroidInjector: DispatchingAndroidInjector<Activity>
override fun activityInjector(): AndroidInjector<Activity> =
dispatchingAndroidInjector
override fun onCreate() {
super.onCreate()
DaggerApplicationComponent.builder()
.application(this)
.build()
.inject(this)
}
}
@Component(modules = [
AndroidInjectionModule::class,
ActivityBindingModule::class,
AppModule::class
/** Other modules **/
])
@Singleton
interface ApplicationComponent {
@Component.Builder
interface Builder {
@BindsInstance
fun application(application: Application): Builder
fun build(): ApplicationComponent
}
fun inject(sampleApp: SampleApp)
}
@Module
public abstract class ActivityBindingModule {
@ContributesAndroidInjector(modules = MainModule.class)
public abstract MainActivity contributeMainActivityInjector();
}
class MainActivity : AppCompatActivity() {
@Inject
lateinit var mainViewModel: mainViewModel
override fun onCreate(savedInstanceState: Bundle?) {
AndroidInjection.inject(this)
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_dashboard)
}
}
@Module
public class MainModule {
@Provides
public static MainViewModelProviderFactory provideMainViewModelProviderFactory(/** some dependencies **/) {
return new MainViewModelProviderFactory(/** some dependencies **/);
}
@Provides
public static MainViewModel provideMainViewModel(MainActivity activity, MainViewModelProviderFactory factory) {
return ViewModelProviders.of(activity, factory).get(MainViewModel.class);
}
}
如您所见,我已将 MainViewModel
直接注入(inject)到 Activity 中。现在,如果我轮换 Activity ,注入(inject)的实例就会不同。
但是,如果我在 MainActivity
中注入(inject) MainViewModelProviderFactory
并执行
ViewModelProviders.of(activity, factory).get(MainViewModel.class)
它返回与之前相同的实例。
我没有发现我的实现有什么问题。
如有任何指点,我们将不胜感激。
最佳答案
所以在查看了ViewModelProvider
的来源之后, ViewModelProviders
, FragmentActivity
是的 dagger2 documentation
我有一个答案..
如果我错了,请随时纠正我..
We must not inject ViewModel directly, we should inject factories instead.
由于这条线 AndroidInjection.inject(this)
,我正面临这个问题.
根据 Dagger 作者
It is crucial to call AndroidInjection.inject() before super.onCreate() in an Activity
让我们在非常高的层次上看看这里出了什么问题..
Activity 将保留它的 ViewModel
使用 onRetainNonConfigurationInstance
旋转并将在 onCreate()
中恢复它
因为我们在调用 super.onCreate()
之前注入(inject), 我们不会得到保留的 MainViewModel
对象,但新对象。
如果您想了解详细信息,请继续阅读..
当 dagger 尝试注入(inject)时 MainViewModel
它叫provideMainViewModel()
MainModule
的方法| ,它调用以下表达式(请记住 super.onCreate()
尚未调用)
ViewModelProviders.of(activity, factory).get(MainViewModel.class)
ViewModelProviders.of
将返回 ViewModelProvider
其中包含 ViewModelStore
的引用资料各自的 Activity 和ViewModelProviderFactory
public static ViewModelProvider of(@NonNull FragmentActivity activity,
@Nullable Factory factory) {
.
.
return new ViewModelProvider(ViewModelStores.of(activity), factory);
}
ViewModelStore.of(activity)
最终会调用 Activity 的getViewModelStore()
因为本例中的 Activity 是 AppCompatActivity
实现ViewModelStoreOwner
AppCompatActivity
创建新的 ViewModelStore
如果它为 null & 持有对它的引用。 ViewModelStore
是 Map<String, ViewModel>
的包装器使用其他方法 clear()
@NonNull
public ViewModelStore getViewModelStore() {
if (this.getApplication() == null) {
throw new IllegalStateException("Your activity is not yet attached to the Application instance. You can't request ViewModel before onCreate call.");
} else {
if (this.mViewModelStore == null) {
this.mViewModelStore = new ViewModelStore();
}
return this.mViewModelStore;
}
}
每当设备旋转时, Activity 都会使用 onRetainNonConfigurationInstance
保留其非配置实例状态并在 onCreate
中恢复它. (例如 mViewModelStore)
ViewModelProvider.get
将尝试获取 ViewModel
来自 Activity 的 ViewModelStore
public <T extends ViewModel> T get(@NonNull String key, @NonNull Class<T> modelClass) {
ViewModel viewModel = mViewModelStore.get(key);
if (modelClass.isInstance(viewModel)) {
//noinspection unchecked
return (T) viewModel;
} else {
//noinspection StatementWithEmptyBody
if (viewModel != null) {
// TODO: log a warning.
}
}
viewModel = mFactory.create(modelClass);
mViewModelStore.put(key, viewModel);
//noinspection unchecked
return (T) viewModel;
}
在这个特定的例子中;因为我们还没有调用 super.onCreate()
方法但实现会询问 factory
创建它并更新相应的 ViewModelStore
.
因此我们最终得到了两个不同的 MainViewModel
对象。
关于android - 旋转后重新创建 ViewModel;如果直接用 dagger2 注入(inject),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51534845/
Glenn Block 和我一直在研究 ViewModel 模式。我们一直在尝试找出与该模式相关的最大痛点,目标是添加框架支持以减轻痛苦。 今晚,格伦发帖,“View Model” – the mov
如果我使用 Views 创建 ViewModel 实例且 ViewModel 没有对 View 的引用的方法,我不知道创建 viewmodel 关系的正确方法是什么。 假设我们有 ChildView
当从缓存中重新加载 ViewModel 时,我需要能够拦截框架并执行重新初始化。由于没有重新创建 ViewModel,我既不能使用 Init()、MvxViewModel.InitFromBundle
我的业务模型(实际上它用于使用 Entity Framework 6 读取数据)看起来像: class Profile : NameDescriptionBase { public virtu
我在swift中玩MVVM遇到了这种情况:我为 tableView 创建了模型,其中包含对象列表和对象计数。有点像 class TableViewViewModel { var count :
我正在研究由以下部分组成的应用程序区域: Explorer - 包含 TreeView PropertyInspector - 包含一个 PropertyGrid 编辑器 - 包含一个 Explore
我正在使用 MVVM-Light,并且我有一个列出了销售人员的 DataGrid 工作。用户可以双击打开一个子窗口,该窗口将在网格上列出他们的销售,用户将能够在该网格下填写一些文本框以添加新的销售。
是否有适当的方法来创建包含 subViewModel 的 C#/WPF ViewModel ? 目标是: 我有一个主窗口。该窗口用于读取/创建图像。窗口上有一个按钮,可以在 2 个 UserContr
首先,如果这很简单,我必须道歉。我对 WPF 和 MVVM 非常陌生,我想确保我没有违反任何 WPF 或 MVVM 概念。此外,对于下面的冗长解释(试图提供所有细节): 我目前正在引用具有所有业务逻辑
我有一个架构问题,以及一个我想提出意见的可能解决方案。 我习惯于 WP7 的 MVVM 架构(尽可能但不幸的是,有时 sdk 似乎朝着相反的方向发展)。 WP7 强制采用 ViewFirst 方法,我
鉴于以下情况: ViewModelA 启动 ViewModelB(当然,通过一个通用 Controller ,它使用 Ioc 和 DI 来解析所需的类型)。 ViewModelB 需要在 ViewMo
在我的 WPF MVVM 应用程序中,使用 Caliburn.Micro,我有一个 ViewModel,CreateServiceViewModel,在单击按钮时,它会在单独的窗口中打开一个 Grid
假设我有一个采用特定 ViewModel 的页面( View ): @model IEnumerable 在这个页面中,我有一个通过另一个 ViewModel(我们称之为 PostModel)发布数据
我有两个相似的 ViewModel,我需要将一个转换为另一个。 这是第一个: using System; using System.Collections.Generic; using System.
我有两个 View 共享来自某个 View 模型的一个可观察集合,但具有不同的 Collection View 参数。在 MVVM Light 中实现它的正确方法是什么?是否支持非静态虚拟机?我如何管
我有 2 个 View 模型 - 主视图模型** 存储 View 模型 StorageViewModel.kt class StorageViewModel @ViewModelInject cons
我有一个 AddressesViewModel 保存用户最喜欢的地址,另一个 SearchViewModel 保存搜索到的地址。当用户搜索地址时,我必须通过检查收藏夹数组来检查该地址是否是收藏夹。正确
首先,我看过this post并没有找到我的问题的答案。 我不确定这是否是汇总 型号 类或聚合 查看型号 类,但这就是我所拥有的: 在我的 WPF(使用 Prism)应用程序中,我有一个 View “
我的 View 中有这些过滤器,它们都会更新 FilterViewModel,然后由它负责过滤数据。其中一个 View ,SearchAddressView 需要 PlacemarkViewModel
依赖的 ViewModel 通过构造函数(IoC 容器)注入(inject)。 示例:ProductSelectionViewModel 使用 ShoppingBasketViewModel。 这是一
我是一名优秀的程序员,十分优秀!