具有相同 return 类型的 @Named 提供者最终给出 java.lang.IllegalArgumentException:重复
@Named providers with same return types end up giving java.lang.IllegalArgumentException: Duplicate
问题来了,
我正在开发一个 LibGDX 项目,其中我有针对不同平台的不同模块。
这是我的 android 模块的样子:
@Module(
includes = {BaseModule.class, NetModule.class},
injects = {DummyProjectActivity.class, DummyProject.class},
overrides = true)
public class DummyProjectAndroidModule {
...
@Provides @Singleton @Named("DummyOne")
DummyInterface provideDummyOne() {
return new DummyOne();
}
@Provides @Singleton @Named("DummyTwo")
DummyInterface provideDummyTwo() {
return new DummyTwo();
}
@Provides @Singleton @Named("DummyConsumer")
DummyConsumer provideDummyConsumer(@Named("DummyOne") DummyInterface dummyOne,
@Named("DummyTwo") DummyInterface dummyTwo) {
return new DummyConsumer(dummyOne, dummyTwo);
}
}
.. 这里是我的桌面模块的样子:
@Module(
includes = {BaseModule.class, NetModule.class},
injects = {DummyProjectDesktop.class, DummyProject.class},
overrides = true)
public class DummyProjectDesktopModule {
嗯,休息也差不多。然而,当我为桌面构建项目时,Android 方面的一切都很好,花花公子,我得到了这个错误,这让我仍然大吃一惊。
Process: net.alicanhasirci.mobile.DummyProject.android, PID: 4603
java.lang.RuntimeException: Unable to start activity ComponentInfo{net.alicanhasirci.mobile.DummyProject.android/net.alicanhasirci.mobile.DummyProject.android.DummyProjectActivity}: java.lang.IllegalArgumentException: Duplicate:
net.alicanhasirci.mobile.android.image.DummyInterface net.alicanhasirci.mobile.DummyProject.android.DummyProjectAndroidModule.provideDummyOne()
net.alicanhasirci.mobile.android.image.DummyInterface net.alicanhasirci.mobile.DummyProject.android.DummyProjectAndroidModule.provideDummyTwo()
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2305)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2365)
at android.app.ActivityThread.access0(ActivityThread.java:148)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1283)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5272)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:909)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:704)
Caused by: java.lang.IllegalArgumentException: Duplicate:
net.alicanhasirci.mobile.android.image.DummyInterface net.alicanhasirci.mobile.DummyProject.android.DummyProjectAndroidModule.provideDummyOne()
net.alicanhasirci.mobile.android.image.DummyInterface net.alicanhasirci.mobile.DummyProject.android.DummyProjectAndroidModule.provideDummyTwo()
at dagger.internal.UniqueMap.put(UniqueMap.java:29)
at dagger.internal.plugins.reflect.ReflectiveModuleAdapter.handleBindings(ReflectiveModuleAdapter.java:104)
at dagger.internal.plugins.reflect.ReflectiveModuleAdapter.getBindings(ReflectiveModuleAdapter.java:89)
at dagger.ObjectGraph$DaggerObjectGraph.makeGraph(ObjectGraph.java:174)
at dagger.ObjectGraph$DaggerObjectGraph.access[=14=]0(ObjectGraph.java:132)
at dagger.ObjectGraph.create(ObjectGraph.java:129)
at net.alicanhasirci.mobile.DummyProject.android.DummyProjectActivity.onCreate(DummyProjectActivity.java:137)
at android.app.Activity.performCreate(Activity.java:5977)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1105)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2258)
现在快速浏览一下 dagger 源代码,我可以看到限定符注释是通过反射收集的,并用作绑定名称的前缀,稍后将用作 UniqueMap 中的键。我的问题似乎出现在这个区域的某个地方,我的限定符没有以某种方式得到处理,但我的桌面构建没有问题...
这里还有一些补充:
ObjectGraph objectGraph = ObjectGraph.create(new DummyProjectAndroidModule());
objectGraph.inject(this);
dp = objectGraph.get(DummyProject.class);
是我如何得到我的 DummyProject
对象,它有一个字段注入 DummyConsumer
。因此:
@Inject @Named("DummyConsumer") DummyConsumer consumer;
我已将 return 类型更改为具体的 类 作为解决方法,但没有人喜欢这种解决方法,因为我们都知道它们会一直困扰着您。
我终于弄明白为什么会出现这个问题了。它是混淆器。除非你在 proguard 配置文件中另外指定,否则它会在修剪注释时混淆生成的代码,而不会导致意外结果。
让 Proguard 和 Dagger 共存的唯一方法是基本上放弃大部分混淆或切换到 Dagger2,正如 Jake Wharton 在 https://github.com/square/dagger/issues/202 上所说的那样。我使用混淆器只是为了避免达到 65k 限制,所以进行必要的配置以避免混淆解决了我的问题。
问题来了,
我正在开发一个 LibGDX 项目,其中我有针对不同平台的不同模块。
这是我的 android 模块的样子:
@Module(
includes = {BaseModule.class, NetModule.class},
injects = {DummyProjectActivity.class, DummyProject.class},
overrides = true)
public class DummyProjectAndroidModule {
...
@Provides @Singleton @Named("DummyOne")
DummyInterface provideDummyOne() {
return new DummyOne();
}
@Provides @Singleton @Named("DummyTwo")
DummyInterface provideDummyTwo() {
return new DummyTwo();
}
@Provides @Singleton @Named("DummyConsumer")
DummyConsumer provideDummyConsumer(@Named("DummyOne") DummyInterface dummyOne,
@Named("DummyTwo") DummyInterface dummyTwo) {
return new DummyConsumer(dummyOne, dummyTwo);
}
}
.. 这里是我的桌面模块的样子:
@Module(
includes = {BaseModule.class, NetModule.class},
injects = {DummyProjectDesktop.class, DummyProject.class},
overrides = true)
public class DummyProjectDesktopModule {
嗯,休息也差不多。然而,当我为桌面构建项目时,Android 方面的一切都很好,花花公子,我得到了这个错误,这让我仍然大吃一惊。
Process: net.alicanhasirci.mobile.DummyProject.android, PID: 4603
java.lang.RuntimeException: Unable to start activity ComponentInfo{net.alicanhasirci.mobile.DummyProject.android/net.alicanhasirci.mobile.DummyProject.android.DummyProjectActivity}: java.lang.IllegalArgumentException: Duplicate:
net.alicanhasirci.mobile.android.image.DummyInterface net.alicanhasirci.mobile.DummyProject.android.DummyProjectAndroidModule.provideDummyOne()
net.alicanhasirci.mobile.android.image.DummyInterface net.alicanhasirci.mobile.DummyProject.android.DummyProjectAndroidModule.provideDummyTwo()
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2305)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2365)
at android.app.ActivityThread.access0(ActivityThread.java:148)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1283)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5272)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:909)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:704)
Caused by: java.lang.IllegalArgumentException: Duplicate:
net.alicanhasirci.mobile.android.image.DummyInterface net.alicanhasirci.mobile.DummyProject.android.DummyProjectAndroidModule.provideDummyOne()
net.alicanhasirci.mobile.android.image.DummyInterface net.alicanhasirci.mobile.DummyProject.android.DummyProjectAndroidModule.provideDummyTwo()
at dagger.internal.UniqueMap.put(UniqueMap.java:29)
at dagger.internal.plugins.reflect.ReflectiveModuleAdapter.handleBindings(ReflectiveModuleAdapter.java:104)
at dagger.internal.plugins.reflect.ReflectiveModuleAdapter.getBindings(ReflectiveModuleAdapter.java:89)
at dagger.ObjectGraph$DaggerObjectGraph.makeGraph(ObjectGraph.java:174)
at dagger.ObjectGraph$DaggerObjectGraph.access[=14=]0(ObjectGraph.java:132)
at dagger.ObjectGraph.create(ObjectGraph.java:129)
at net.alicanhasirci.mobile.DummyProject.android.DummyProjectActivity.onCreate(DummyProjectActivity.java:137)
at android.app.Activity.performCreate(Activity.java:5977)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1105)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2258)
现在快速浏览一下 dagger 源代码,我可以看到限定符注释是通过反射收集的,并用作绑定名称的前缀,稍后将用作 UniqueMap 中的键。我的问题似乎出现在这个区域的某个地方,我的限定符没有以某种方式得到处理,但我的桌面构建没有问题...
这里还有一些补充:
ObjectGraph objectGraph = ObjectGraph.create(new DummyProjectAndroidModule());
objectGraph.inject(this);
dp = objectGraph.get(DummyProject.class);
是我如何得到我的 DummyProject
对象,它有一个字段注入 DummyConsumer
。因此:
@Inject @Named("DummyConsumer") DummyConsumer consumer;
我已将 return 类型更改为具体的 类 作为解决方法,但没有人喜欢这种解决方法,因为我们都知道它们会一直困扰着您。
我终于弄明白为什么会出现这个问题了。它是混淆器。除非你在 proguard 配置文件中另外指定,否则它会在修剪注释时混淆生成的代码,而不会导致意外结果。
让 Proguard 和 Dagger 共存的唯一方法是基本上放弃大部分混淆或切换到 Dagger2,正如 Jake Wharton 在 https://github.com/square/dagger/issues/202 上所说的那样。我使用混淆器只是为了避免达到 65k 限制,所以进行必要的配置以避免混淆解决了我的问题。