gpt4 book ai didi

android - 如何用 Dagger2 @Inject AndroidViewModel?

转载 作者:行者123 更新时间:2023-12-04 01:12:30 25 4
gpt4 key购买 nike

我目前正在调查 Dagger2 的使用情况在我的 Android 应用程序中。

implementation 'com.google.dagger:dagger:2.21'
annotationProcessor 'com.google.dagger:dagger-compiler:2.21'

implementation 'com.google.dagger:dagger-android:2.21'
implementation 'com.google.dagger:dagger-android-support:2.21'
annotationProcessor 'com.google.dagger:dagger-android-processor:2.21'

我已经设法 @Inject ViewModel 及其关联的存储库

使用以下代码:-
import java.util.Map;

import javax.inject.Inject;
import javax.inject.Provider;
import javax.inject.Singleton;

import androidx.lifecycle.ViewModel;
import androidx.lifecycle.ViewModelProvider;

@Singleton
public class DaggerViewModelFactory implements ViewModelProvider.Factory {

private final Map<Class<? extends ViewModel>, Provider<ViewModel>> creators;

@Inject
public DaggerViewModelFactory(final Map<Class<? extends ViewModel>, Provider<ViewModel>> creators) {
this.creators = creators;
}

@SuppressWarnings("unchecked")
@Override
public <T extends ViewModel> T create(final Class<T> modelClass) {
Provider<? extends ViewModel> creator = creators.get(modelClass);

if (creator == null) {
for (Map.Entry<Class<? extends ViewModel>, Provider<ViewModel>> entry : creators.entrySet()) {
if (modelClass.isAssignableFrom(entry.getKey())) {
creator = entry.getValue();
break;
}
}
}

if (creator == null) {
throw new IllegalArgumentException("unknown model class " + modelClass);
}

try {
return (T) creator.get();
} catch (final Exception e) {
throw new RuntimeException(e);
}
}
}

import androidx.lifecycle.ViewModel;
import androidx.lifecycle.ViewModelProvider;
import dagger.Binds;
import dagger.Module;
import dagger.multibindings.IntoMap;

@Module
public abstract class ViewModelModule {

@Binds
abstract ViewModelProvider.Factory bindViewModelFactory(final DaggerViewModelFactory factory);

@Binds
@IntoMap
@ViewModelKey(StilettoViewModel.class)
abstract ViewModel provideStilettoViewModel(final StilettoViewModel stilettoViewModel);
}

但是我的一些 ViewModel 是 androidx.lifecycle.AndroidViewModel .

我创建了这个 ViewModelFactory:-
import android.app.Application;

import java.util.Map;

import javax.inject.Provider;
import javax.inject.Singleton;

import androidx.annotation.NonNull;
import androidx.lifecycle.AndroidViewModel;
import androidx.lifecycle.ViewModel;
import androidx.lifecycle.ViewModelProvider;

@Singleton
public class DaggerAndroidViewModelFactory extends ViewModelProvider.AndroidViewModelFactory {

private final Application application;

private Map<Class<? extends AndroidViewModel>, Provider<AndroidViewModel>> creators;


/**
* Creates a {@code AndroidViewModelFactory}
*
* @param application an application to pass in {@link AndroidViewModel}
*/
public DaggerAndroidViewModelFactory(@NonNull final Application application) {
super(application);
this.application = application;
}


@NonNull
@Override
public <T extends ViewModel> T create(@NonNull final Class<T> modelClass) {
return super.create(modelClass);
}
}

和这个 Dagger 模块
import androidx.lifecycle.AndroidViewModel;
import androidx.lifecycle.ViewModelProvider;
import dagger.Binds;
import dagger.Module;
import dagger.multibindings.IntoMap;

@Module
public abstract class ViewModelModule {

@Binds
abstract ViewModelProvider.AndroidViewModelFactory bindAndroidViewModelFactory(final DaggerAndroidViewModelFactory factory);

@Binds
@IntoMap
@ViewModelKey(MyAndroidViewModel.class)
abstract AndroidViewModel provideArticlesViewModel(final ArticlesViewModel articlesViewModel);
}

当我收到此错误时,此代码将无法构建
error: [Dagger/MissingBinding] MyAndroidViewModel cannot be provided without an @Inject constructor or an @Provides-annotated method.

是否可以注入(inject) androidx.lifecycle.AndroidViewModel与 Dagger 2?

我的实现哪里出了问题?

最佳答案

如果您有 @Module@Provides Application (或者你使用 @BindsInstance + @Component.Builder ,老实说两者都有效):

@Module
public class AppModule {
private final Application app;

public AppModule(Application app) {
this.app = app;
}

@Provides
Application app() { return app; }
}


@Component(modules={AppModule.class, ...})
@Singleton
public interface AppComponent {
}

然后现在而不是使用 AndroidViewModel:
public class MyViewModel extends AndroidViewModel {
public MyViewModel(Application app) {
...
}
}

您可以将常规 ViewModel 与 @Inject 一起使用构造函数:
public class MyViewModel extends ViewModel {
@Inject
MyViewModel(Application app) {
...
}
}

您可以通过 DaggerViewModelFactory 像任何其他常规 ViewModel 类一样使用它。 .

关于android - 如何用 Dagger2 @Inject AndroidViewModel?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55142614/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com