error: [Dagger/DependencyCycle] Found a dependency cycle error after using ActivityRetainedScoped
error: [Dagger/DependencyCycle] Found a dependency cycle error after using ActivityRetainedScoped
我正在开发使用 MVVM、Room 和匕首柄的应用程序,我已经实现了处理服务器响应、远程数据源、视图模型和所有这些东西的第一部分,并且运行良好,但是在我实现了数据库模块之后,当我尝试构建
时出现此错误
public abstract static class SingletonC implements BaseApplication_GeneratedInjector,
^
com.test.dummyappv3.data.database.ItemDAO is injected at
com.test.dummyappv3.di.DatabaseModule.provideDao(itemDAO)
com.test.dummyappv3.data.database.ItemDAO is injected at
com.test.dummyappv3.data.LocalDataSource(itemDAO)
com.test.dummyappv3.data.LocalDataSource is injected at
com.test.dummyappv3.data.Repository(�, localDataSource)
com.test.dummyappv3.data.Repository is injected at
com.test.dummyappv3.viewmodels.PostViewModel(repository)
com.test.dummyappv3.viewmodels.PostViewModel is injected at
com.test.dummyappv3.viewmodels.PostViewModel_HiltModules.BindsModule.binds(vm)
@dagger.hilt.android.internal.lifecycle.HiltViewModelMap java.util.Map<java.lang.String,javax.inject.Provider<androidx.lifecycle.ViewModel>> is requested at
dagger.hilt.android.internal.lifecycle.HiltViewModelFactory.ViewModelFactoriesEntryPoint.getHiltViewModelMap() [com.test.dummyappv3.BaseApplication_HiltComponents.SingletonC ? com.test.dummyappv3.BaseApplication_HiltComponents.ActivityRetainedC ? com.test.dummyappv3.BaseApplication_HiltComponents.ViewModelC]
我认为它与 Repository Class
中的 ActivityRetainedScoped
有关
@ActivityRetainedScoped
public class Repository {
public RemoteDataSource remoteDataSource;
public LocalDataSource localDataSource;
@Inject
public Repository(RemoteDataSource remoteDataSource, LocalDataSource localDataSource) {
this.remoteDataSource = remoteDataSource;
this.localDataSource = localDataSource;
}
}
数据库模块
@InstallIn(SingletonComponent.class)
@Module
public class DatabaseModule {
@Singleton
@Provides
public static ItemsDatabase provideDatabase(@ApplicationContext Context context){
return Room.databaseBuilder(context,ItemsDatabase.class,"items_database")
.fallbackToDestructiveMigration()
.build();
}
@Singleton
@Provides
public static ItemDAO provideDao(ItemDAO itemDAO){
return itemDAO;
}
}
远程数据源
private final PostAPIService postAPIService;
@Inject
public RemoteDataSource(PostAPIService postAPIService) {
this.postAPIService = postAPIService;
}
public Observable<PostList> getPostList(String URL) {
return postAPIService.getPostList(URL);
}
public Observable<PostList> getPostListByLabel(String URL) {
return postAPIService.getPostListByLabel(URL);
}
}
本地数据源
public class LocalDataSource {
private final ItemDAO itemDAO;
@Inject
public LocalDataSource(ItemDAO itemDAO) {
this.itemDAO = itemDAO;
}
public Completable insertItem(Item item){
return itemDAO.insert(item);
}
public Flowable<List<Item>> getAlItems(){
return itemDAO.getAlItems();
}
}
最后是视图模型
@HiltViewModel
public class PostViewModel extends ViewModel {
public static final String TAG = "PostViewModel";
private Repository repository = null;
public MutableLiveData<PostList> postListMutableLiveData = new MutableLiveData<>();
public MutableLiveData<String> finalURL = new MutableLiveData<>();
public MutableLiveData<String> token = new MutableLiveData<>();
public MutableLiveData<String> label = new MutableLiveData<>();
public MutableLiveData<Boolean> ifAnythingWrongHappened = new MutableLiveData<>();
@Inject
public PostViewModel(Repository repository) {
this.repository = repository;
}
public final LiveData<List<Item>> getAllPostsFromDB
= LiveDataReactiveStreams.fromPublisher(repository.localDataSource.getAlItems());
@SuppressLint("CheckResult")
public void getPosts() {
ifAnythingWrongHappened.setValue(false);
Log.e(TAG, finalURL.getValue());
repository.remoteDataSource.getPostList(finalURL.getValue())
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<PostList>() {
@Override
public void onSubscribe(@io.reactivex.rxjava3.annotations.NonNull Disposable d) {
}
@Override
public void onNext(@io.reactivex.rxjava3.annotations.NonNull PostList postList) {
Log.e(TAG, postList.getNextPageToken());
token.setValue(postList.getNextPageToken());
postListMutableLiveData.setValue(postList);
for (int i = 0; i < postList.getItems().size(); i++) {
repository.localDataSource.insertItem(postList.getItems().get(i))
.subscribeOn(Schedulers.computation())
.subscribe(new CompletableObserver() {
@Override
public void onSubscribe(@io.reactivex.rxjava3.annotations.NonNull Disposable d) {
}
@Override
public void onComplete() {
}
@Override
public void onError(@io.reactivex.rxjava3.annotations.NonNull Throwable e) {
Log.e(TAG, "onError: "+e.getMessage() );
ifAnythingWrongHappened.setValue(true);
}
});
}
finalURL.setValue(finalURL.getValue() + "&pageToken=" + token.getValue());
}
@Override
public void onError(@io.reactivex.rxjava3.annotations.NonNull Throwable e) {
Log.e(TAG, e.getMessage() + e.getCause());
ifAnythingWrongHappened.setValue(true);
}
@Override
public void onComplete() {
}
});
}
我试图删除这个 @ActivityRetainedScoped
和 @ApplicationContext
但同样的错误我也尝试了视图模型中的 @ViewModelScoped
@Singleton
@Provides
public static ItemDAO provideDao(ItemDAO itemDAO){
return itemDAO;
}
这就是循环依赖。要查看的错误跟踪的重要部分是从第一个条目 (ItemDAO
) 到并排除相同 class 的第二次出现的所有内容。错误消息的其余部分显示了依赖关系图中 ItemDAO
的一种用法,因为 Dagger 仅验证可达的依赖关系。
我假设你打算做这样的事情:
@Singleton
@Provides
public static ItemDAO provideDao(ItemsDatabase database){
return database.itemDAO();
}
我正在开发使用 MVVM、Room 和匕首柄的应用程序,我已经实现了处理服务器响应、远程数据源、视图模型和所有这些东西的第一部分,并且运行良好,但是在我实现了数据库模块之后,当我尝试构建
时出现此错误public abstract static class SingletonC implements BaseApplication_GeneratedInjector,
^
com.test.dummyappv3.data.database.ItemDAO is injected at
com.test.dummyappv3.di.DatabaseModule.provideDao(itemDAO)
com.test.dummyappv3.data.database.ItemDAO is injected at
com.test.dummyappv3.data.LocalDataSource(itemDAO)
com.test.dummyappv3.data.LocalDataSource is injected at
com.test.dummyappv3.data.Repository(�, localDataSource)
com.test.dummyappv3.data.Repository is injected at
com.test.dummyappv3.viewmodels.PostViewModel(repository)
com.test.dummyappv3.viewmodels.PostViewModel is injected at
com.test.dummyappv3.viewmodels.PostViewModel_HiltModules.BindsModule.binds(vm)
@dagger.hilt.android.internal.lifecycle.HiltViewModelMap java.util.Map<java.lang.String,javax.inject.Provider<androidx.lifecycle.ViewModel>> is requested at
dagger.hilt.android.internal.lifecycle.HiltViewModelFactory.ViewModelFactoriesEntryPoint.getHiltViewModelMap() [com.test.dummyappv3.BaseApplication_HiltComponents.SingletonC ? com.test.dummyappv3.BaseApplication_HiltComponents.ActivityRetainedC ? com.test.dummyappv3.BaseApplication_HiltComponents.ViewModelC]
我认为它与 Repository Class
中的ActivityRetainedScoped
有关
@ActivityRetainedScoped
public class Repository {
public RemoteDataSource remoteDataSource;
public LocalDataSource localDataSource;
@Inject
public Repository(RemoteDataSource remoteDataSource, LocalDataSource localDataSource) {
this.remoteDataSource = remoteDataSource;
this.localDataSource = localDataSource;
}
}
数据库模块
@InstallIn(SingletonComponent.class)
@Module
public class DatabaseModule {
@Singleton
@Provides
public static ItemsDatabase provideDatabase(@ApplicationContext Context context){
return Room.databaseBuilder(context,ItemsDatabase.class,"items_database")
.fallbackToDestructiveMigration()
.build();
}
@Singleton
@Provides
public static ItemDAO provideDao(ItemDAO itemDAO){
return itemDAO;
}
}
远程数据源
private final PostAPIService postAPIService;
@Inject
public RemoteDataSource(PostAPIService postAPIService) {
this.postAPIService = postAPIService;
}
public Observable<PostList> getPostList(String URL) {
return postAPIService.getPostList(URL);
}
public Observable<PostList> getPostListByLabel(String URL) {
return postAPIService.getPostListByLabel(URL);
}
}
本地数据源
public class LocalDataSource {
private final ItemDAO itemDAO;
@Inject
public LocalDataSource(ItemDAO itemDAO) {
this.itemDAO = itemDAO;
}
public Completable insertItem(Item item){
return itemDAO.insert(item);
}
public Flowable<List<Item>> getAlItems(){
return itemDAO.getAlItems();
}
}
最后是视图模型
@HiltViewModel
public class PostViewModel extends ViewModel {
public static final String TAG = "PostViewModel";
private Repository repository = null;
public MutableLiveData<PostList> postListMutableLiveData = new MutableLiveData<>();
public MutableLiveData<String> finalURL = new MutableLiveData<>();
public MutableLiveData<String> token = new MutableLiveData<>();
public MutableLiveData<String> label = new MutableLiveData<>();
public MutableLiveData<Boolean> ifAnythingWrongHappened = new MutableLiveData<>();
@Inject
public PostViewModel(Repository repository) {
this.repository = repository;
}
public final LiveData<List<Item>> getAllPostsFromDB
= LiveDataReactiveStreams.fromPublisher(repository.localDataSource.getAlItems());
@SuppressLint("CheckResult")
public void getPosts() {
ifAnythingWrongHappened.setValue(false);
Log.e(TAG, finalURL.getValue());
repository.remoteDataSource.getPostList(finalURL.getValue())
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<PostList>() {
@Override
public void onSubscribe(@io.reactivex.rxjava3.annotations.NonNull Disposable d) {
}
@Override
public void onNext(@io.reactivex.rxjava3.annotations.NonNull PostList postList) {
Log.e(TAG, postList.getNextPageToken());
token.setValue(postList.getNextPageToken());
postListMutableLiveData.setValue(postList);
for (int i = 0; i < postList.getItems().size(); i++) {
repository.localDataSource.insertItem(postList.getItems().get(i))
.subscribeOn(Schedulers.computation())
.subscribe(new CompletableObserver() {
@Override
public void onSubscribe(@io.reactivex.rxjava3.annotations.NonNull Disposable d) {
}
@Override
public void onComplete() {
}
@Override
public void onError(@io.reactivex.rxjava3.annotations.NonNull Throwable e) {
Log.e(TAG, "onError: "+e.getMessage() );
ifAnythingWrongHappened.setValue(true);
}
});
}
finalURL.setValue(finalURL.getValue() + "&pageToken=" + token.getValue());
}
@Override
public void onError(@io.reactivex.rxjava3.annotations.NonNull Throwable e) {
Log.e(TAG, e.getMessage() + e.getCause());
ifAnythingWrongHappened.setValue(true);
}
@Override
public void onComplete() {
}
});
}
我试图删除这个 @ActivityRetainedScoped
和 @ApplicationContext
但同样的错误我也尝试了视图模型中的 @ViewModelScoped
@Singleton
@Provides
public static ItemDAO provideDao(ItemDAO itemDAO){
return itemDAO;
}
这就是循环依赖。要查看的错误跟踪的重要部分是从第一个条目 (ItemDAO
) 到并排除相同 class 的第二次出现的所有内容。错误消息的其余部分显示了依赖关系图中 ItemDAO
的一种用法,因为 Dagger 仅验证可达的依赖关系。
我假设你打算做这样的事情:
@Singleton
@Provides
public static ItemDAO provideDao(ItemsDatabase database){
return database.itemDAO();
}