我的应用程序中有不同的模块遵循干净的架构,有些是纯 kotlin 模块和其他 android 模块,但是当我尝试编译应用程序时,我收到重复的类错误。
* What went wrong:
Execution failed for task ':app:checkDebugDuplicateClasses'.
> A failure occurred while executing com.android.build.gradle.internal.tasks.CheckDuplicatesRunnable
> Duplicate class dagger.hilt.codegen.OriginatingElement found in modules jetified-hilt-android-2.28.3-alpha-runtime (com.google.dagger:hilt-android:2.28.3-alpha) and jetified-hilt-android-compiler-2.28.3-alpha (com.google.dagger:hilt-android-compiler:2.28.3-alpha)
Duplicate class dagger.hilt.processor.internal.aggregateddeps.AggregatedDeps found in modules jetified-hilt-android-2.28.3-alpha-runtime (com.google.dagger:hilt-android:2.28.3-alpha) and jetified-hilt-android-compiler-2.28.3-alpha (com.google.dagger:hilt-android-compiler:2.28.3-alpha)
Duplicate class dagger.shaded.auto.common.AnnotationMirrors found in the following modules: jetified-dagger-compiler-2.28.3 (com.google.dagger:dagger-compiler:2.28.3), jetified-dagger-spi-2.28.3 (com.google.dagger:dagger-spi:2.28.3) and jetified-hilt-android-compiler-2.28.3-alpha (com.google.dagger:hilt-android-compiler:2.28.3-alpha)
Duplicate class dagger.shaded.auto.common.AnnotationMirrors$1 found in the following modules: jetified-dagger-compiler-2.28.3 (com.google.dagger:dagger-compiler:2.28.3), jetified-dagger-spi-2.28.3 (com.google.dagger:dagger-spi:2.28.3) and jetified-hilt-android-compiler-2.28.3-alpha (com.google.dagger:hilt-android-compiler:2.28.3-alpha)
Duplicate class dagger.shaded.auto.common.AnnotationMirrors$2 found in the …Run Code Online (Sandbox Code Playgroud) 我实现了完整的匕首实现,如添加组件,提供,模块和Inject,最后我面临以下问题,请提出解决方案
Program type already present: dagger.internal.codegen.DaggerStreams$$Lambda$12
Run Code Online (Sandbox Code Playgroud)
这是gradle代码
android {
compileSdkVersion 27
defaultConfig {
applicationId "app.rxjavaexample.com.daggerexample"
minSdkVersion 15
targetSdkVersion 27
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.android.support:appcompat-v7:27.0.2'
implementation 'com.android.support.constraint:constraint-layout:1.1.3'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
implementation 'com.google.dagger:dagger:2.16'
implementation 'com.google.dagger:dagger-compiler:2.16'
implementation 'com.android.support:design:27.0.2'
annotationProcessor 'com.google.dagger:dagger-compiler:2.16'
implementation 'com.android.support:recyclerview-v7:27.0.2'
}
Run Code Online (Sandbox Code Playgroud) 我正在使用 dagger 2 进行依赖注入,但陷入了字段注入的困境。以下是带有代码示例的完整场景:
假设我们有一个 A 类,它依赖于 B 库
class A {
@Inject
B b;
}
Run Code Online (Sandbox Code Playgroud)
B 模块:
@Module
public class BModule {
@Provides
@Singleton
public B provideB() {
return new C.methodA();
// C - static class; C.methodA returns B
}
}
Run Code Online (Sandbox Code Playgroud)
但是当我尝试在 A 类中使用时,我会得到空指针异常,但如果我使用构造函数注入b执行相同的操作,那么它会完美运行。我可以保证组件和其他依赖项都很好,因为构造函数部分可以正常工作。
A 是某个其他类(我们称之为 X)的依赖项,并且 A 正在使用构造函数注入进行初始化(已测试)。另外,X 被注入为void inject(X x);
我有两个问题:
PS:我刚刚分享了部分代码,因为存在多个依赖项,所以只是想解释一下场景。如果问题/场景仍然不清楚或需要更多信息,请告诉我。
谢谢。
我在这一行收到“无法解析方法”错误:
AndroidInjection.inject(this);
Run Code Online (Sandbox Code Playgroud)
我正在尝试注入一个片段。这是整个班级:
public class ShowWalletFragment extends BaseFragment {
@Inject
ShowWalletViewModelFactory showWalletViewModelFactory;
ShowWalletViewModel showWalletViewModel;
private Wallet wallet;
private static final String TITLE_BALANCE = "Balance";
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
return super.onCreateView(inflater, container, savedInstanceState);
//butterknife bind
}
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
showWalletViewModel = ViewModelProviders.of(this, showWalletViewModelFactory).
get(ShowWalletViewModel.class);
}
@Override
public void onAttach(Context context) {
AndroidInjection.inject(this);
super.onAttach(context);
}
}
Run Code Online (Sandbox Code Playgroud)
为什么它不能解决“这个”?有什么建议?如果您需要我的应用程序中的更多代码,请告诉我。
编辑1:
implementation 'com.google.dagger:dagger:2.19'
annotationProcessor 'com.google.dagger:dagger-compiler:2.19'
implementation 'com.google.dagger:dagger-android:2.19'
implementation 'com.google.dagger:dagger-android-support:2.19'
annotationProcessor …Run Code Online (Sandbox Code Playgroud) 我正在尝试将 ViewModel 注入适配器中。注入 Fragment 时效果很好。
\n视图模型:
\nclass HomeViewModel @ViewModelInject constructor(\n): ViewModel() \nRun Code Online (Sandbox Code Playgroud)\n分段:
\n@AndroidEntryPoint\nclass HomeFragment : BaseFragment<FragmentHomeBinding, HomeViewModel>(\nR.layout.fragment_home\n) {\n\nprivate val viewModel: HomeViewModel by viewModels()\nRun Code Online (Sandbox Code Playgroud)\n目前为止没有问题。但是当我尝试注入适配器时出现问题。
\nclass HomeListAdapter @Inject constructor(\n): BaseListAdapter<Users>(\nitemsSame = { old, new -> old.username == new.username },\ncontentsSame = { old, new -> old == new }\n) {\n\n\n\nprivate val viewModel: HomeViewModel by viewModels() //viewModels() unresolved reference\nRun Code Online (Sandbox Code Playgroud)\n\n更新:
\n如果我尝试使用构造函数注入或字段注入,我会收到以下错误:
\n error: [Dagger/MissingBinding] ***.home.HomeViewModel cannot be provided without an @Inject constructor or …Run Code Online (Sandbox Code Playgroud) 我有一个活动视图模型
\n@HiltViewModel\nclass MainViewModel @Inject constructor(\nprivate val repository: UserRepository\n) : ViewModel() {\n\n}\nRun Code Online (Sandbox Code Playgroud)\n存储库接口
\ninterface UserRepository {\nsuspend fun loginUser(username: String, password: String): Pair<Boolean, String>\n}\nRun Code Online (Sandbox Code Playgroud)\n用户数据源类如下
\ninternal class UserDataSource @Inject constructor(private val octaveApi: OctaveApi) :\nUserRepository {\n\noverride suspend fun loginUser(username: String, password: String): Pair<Boolean, String> {\n return Pair(false, "unsucess")\n}\n}\nRun Code Online (Sandbox Code Playgroud)\n这是我的匕首实现
\n@Module\n@InstallIn(SingletonComponent::class)\nabstract class ApiModule {\n\n @Module\n @InstallIn(SingletonComponent::class)\n object Providers {\n\n @Provides\n @Singleton\n internal fun provideOctaveApi(retrofit: Retrofit): OctaveApi =\n retrofit.create(OctaveApi::class.java)\n }\n}\n\n@Module\n@InstallIn(ActivityRetainedComponent::class)\nabstract class RetainedDataModule {\n\n @Binds\n internal abstract fun bindUserRepository(userDataSource: …Run Code Online (Sandbox Code Playgroud) 我想了解dagger2并在我的应用程序中实现.我已经阅读了很多关于它的好处.除非我完全理解,否则我无法在我的应用中获得它的好处.
我已经理解了@Module和@Inject.令我困惑的是@Component.我几乎没有相关的问题.
Module提供对象实例,Inject使用它.为什么我们之间需要组件?是否真的有必要缩小差距?我们可以使用没有任何方法的空接口组件吗?
构造函数对于模块类是否真的必要?如果模块类中没有构造函数,我们可以使用空构造函数初始化模块类吗?
为什么我们不能直接实例化模块类并构建依赖图而不是创建组件然后初始化它?
到目前为止,我在组件接口中只看到了两种方法
一个.void inject(活动/服务/片段); - 为什么我们需要为此方法提供活动或服务或片段的实例?为什么我们不能有这样的东西 -
void inject(); - 组件是否仍会生成依赖图?
我们可以从活动或服务以外的其他类注入或者像这样的片段 -
void inject(DataManager dataManager);
如果DataManager是单例实例怎么办?
湾 改造getRetrofit(); 这种方法和上面的方法有什么区别?为什么不采用任何输入参数?
我读到@Singleton只是匕首的范围.我们怎样才能真正创建一个在应用程序的生命周期内存在的单例对象?
假设我想使用dagger构建一个DataManager实例.它只有一个依赖.我为此编写了一个模块类和一个组件接口.如果我想在MainActivity中使用它,我会用它作为
@Inject DataManager dataManager;
...
@覆盖
protected void onCreate(Bundle savedInstanceState){
DataManagerComponent.Builder().DataManagerModule(new DataManagerModule()).build();
}
我想在许多其他活动中使用这个数据管理器,我不希望它是单例.我想将它保持在我使用它的当前活动范围.所以我会用
@Inject DataManager dataManager;
得到那个实例.我应该写
DataManagerComponent.Builder...........
Run Code Online (Sandbox Code Playgroud)
在每个活动oncreate()我使用@Inject DataManager dataManager?如果我必须写它,它不会创建更多的样板代码而不是简单地使用
DataManager dataManager = new DataManager();
假设有4个对象,它们相互依赖,如D依赖于C,C依赖于B等.
D - > C - > B - > A.
让我们假设我已经编写了模块类并为所有4提供了方法.如果我尝试在任何ActivityA中注入D
@Inject D d;
C,B,A会自动实例化吗?
让我们假设在ActivityB中我只需要注入B.如果我注入B就好了
@Inject B b;
匕首会再创造B和A吗?或者它会使用已经创建的那些?
如果有人花时间回答我的所有问题,我感激不尽.我不指望详细的答案.如果澄清这个概念就好了.期待着回应.提前致谢.