【问题标题】:How to make a ViewModelFactory with an id parameter in its constructor injectable?如何使构造函数中带有 id 参数的 ViewModelFactory 可注入?
【发布时间】:2018-05-19 07:06:25
【问题描述】:

我在带有 Dagger 的 Android 中使用 ViewModel 来管理依赖项。我的 ViewModel 将在创建时从 MainActivity 获取一个 id。所以我在这里有这些代码:

活动中:

@inject ViewModelProviderFactory mViewModelFactory;
ViewModelProviders.of(this, mViewModelFactory).get(MyViewModel.class);

我的工厂供应商:

public class ViewModelProviderFactory implements ViewModelProvider.Factory {

    private int id;

    @inject
    public ViewModelProviderFactory(int id) {
        this.id = id;
    }

    @Override
    public <T extends ViewModel> T create(Class<T> modelClass) {
        return new MyViewModel(id);
    }    
}

为了工作,我需要在我的模块中添加一个参数:

@Module
public class MainActivityModule {
    int id;
    public MainActivityModule(int id){ 
        this.id = id;
    }
    @Provides
    ViewModelProvider.Factory mainViewModelProvider() {
        return new ViewModelProviderFactory<>(id);
    }
}

或者我可以直接在组件中做它并使其抽象。 在新的 Dagger 中,我可以使用 Dagger 类来制作活动或片段组件。所以我应该为每个活动创建子组件和一个构建器以及我应该编写的其他代码的色调。

是否有任何简单和更好的方法来防止这些额外的代码,或者我最好通过在这样的活动中调用一个新工厂来创建我的工厂?:

ViewModelProviders.of(this, new ViewModelProviderFactory(id)).get(MyViewModel.class);

【问题讨论】:

    标签: android dagger android-viewmodel


    【解决方案1】:

    在我看来,从Activity 调用new ViewModelProviderFactory(id) 是更简单的解决方案。但是,我不会使用Activity 中的构造函数直接。相反,我会创建工厂(是的,工厂的工厂......),我将其注入Activity

    这是一个例子:

    class FactoryOfFactory {
    
        @Inject
        FactoryOfFactory() {}
    
        ViewModelProvider.Factory create(int id) {
            // ViewModelProviderFactory can now by just an anonymous class
            return new ViewModelProvider.Factory() {
                @Override
                public <T extends ViewModel> T create(Class<T> modelClass) {
                    return (T) new MyViewModel(id);
                }
            };
        }
    }
    

    及用法:

    class ClientActivity extends AppCompatActivity {
    
        @Inject
        FactoryOfFactory factoryOfFactory;
    
        @Override
        protected void onCreate(@Nullable final Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
    
            final int id = 123;
            ViewModelProviders.of(this, factoryOfFactory.create(id)).get(MyViewModel.class);
        }
    }
    

    该方法还有如下解决方案:如果MyViewModel需要另外的依赖(Activity没有提供),我们可以很容易地添加它们(无需修改Activity):

    class MyViewModel extends ViewModel {
        MyViewModel(int id, AnotherDependency anotherDependency) { }
    }
    
    class FactoryOfFactory {
    
        private final AnotherDependency anotherDependency; // added
    
        @Inject
        FactoryOfFactory(final AnotherDependency anotherDependency) {  // modified
            this.anotherDependency = anotherDependency; // added
        }
    
        ViewModelProvider.Factory create(int id) {
            // ViewModelProviderFactory can now by just an anonymous class
            return new ViewModelProvider.Factory() {
                @Override
                public <T extends ViewModel> T create(Class<T> modelClass) {
                    return (T) new MyViewModel(id, anotherDependency);  // modified
                }
            };
        }
    }
    

    当然,我相信存在比FactoryOfFactory 更好的名字;)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-02-04
      • 1970-01-01
      • 2019-03-10
      • 1970-01-01
      • 1970-01-01
      • 2018-03-27
      • 1970-01-01
      相关资源
      最近更新 更多