2014-11-06 97 views
0

我想用Android的依赖注入框架替换我们的组件注册表(使用dexfile类加载器魔术)。 第一次尝试是匕首。Dagger 1.x @Inject抛出IllegalArgumentException

试图当我得到以下错误:

11-06 13:05:41.040 16269-16269/com.daggertoolkitexample E/AndroidRuntime﹕ FATAL EXCEPTION: main 
java.lang.RuntimeException: Unable to start activity ComponentInfo{daggertoolkitexample/com.dagger.MyActivity}: java.lang.IllegalArgumentException: No inject registered for members/com.dagger.MyActivity. You must explicitly add it to the 'injects' option in one of your modules. 
     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2295) 
     ... 
Caused by: java.lang.IllegalArgumentException: No inject registered for members/com.dagger.MyActivity. You must explicitly add it to the 'injects' option in one of your modules. 
     at dagger.ObjectGraph$DaggerObjectGraph.getInjectableTypeBinding(ObjectGraph.java:302) 
     at dagger.ObjectGraph$DaggerObjectGraph.inject(ObjectGraph.java:279) 
     at com.dagger.MyApplication.inject(MyApplication.java:39) 
     at com.dagger.MyBaseActivity.onCreate(MyBaseActivity.java:18) 
     at com.dagger.MyActivity.onCreate(MyActivity.java:22) 
     at android.app.Activity.performCreate(Activity.java:5372) 
     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1104) 
     ... 

我能解决这个问题,如果我在@Module注入我的活动。其工作无一例外。

@Module(
    library = true, 
    injects = MyActivity.class) 
public class AuthManagementModul {...}` 

但这不是我想要的。 我不能也想知道我的组件的所有用户。

有没有人知道怎么回事?

这里是我的示例代码:

public class MyBaseActivity extends ActionBarActivity { 

    @Override protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    ((MyApplication) getApplication()).inject(this); 
    } 
} 

...

public class MyActivity extends MyBaseActivity { 

    @Inject AuthManagement authManagement; 

    ... 
} 

...

public class MyApplication extends Application{ 

    private ObjectGraph graph; 

    @Override 
    public void onCreate() { 
    super.onCreate(); 
    graph = ObjectGraph.create(new AuthManagementModul(this)); 
    } 

    public void inject(Object object) { 
    graph.inject(object); 
    } 
} 

...

@Module(
    library = true 
) 
public class AuthManagementModul { 

    private final Application application; 

    public AuthManagementModul(Application application) { 
    this.application = application; 
    } 

    @Provides 
    @Singleton 
    AuthManagement provideAuthManagement() { 
    return new AuthManagementImpl(application); 
} 
} 

回答

0

在这种情况下,您不想向AuthManagementModul添加injects =,而是添加到包含它的活动特定模块。

Dagger 1.x使用injects =作为图形根要分析的信号,因此它们必须存在 - 但它们不需要存在于叶节点库模块上 - 仅在该活动使用的模块上。考虑在多个分割线打破了你的模块,像这样:

@Module(
    injects = { 
    ... all your activities 
    }, 
    includes = { 
    AuthManagementModul.class, 
    ApplicationModule.class 
    } 
) 
class EntryPointsModule {} 

@Module(library = true, complete = false) 
class AuthManagementModul { 
    @Provides 
    @Singleton 
    AuthManagement provideAuthManagement(Application application) { 
    return new AuthManagementImpl(application); 
    } 
} 

@Module(library = true)  
class ApplicationModule { 

    private final Application application; 

    public ApplicationModule(Application application) { 
    this.application = application; 
    } 

    @Provides 
    @Singleton 
    Application application() { 
    return application; 
    } 
} 

然后创建像这样的图表:

public class MyApplication extends Application{ 

    private ObjectGraph graph; 

    @Override 
    public void onCreate() { 
    super.onCreate(); 
    // AuthManagementModul is automatically included because it has a default 
    // constructor and is included by EntryPointsModule 
    graph = ObjectGraph.create(new EntryPointsModule(), new ApplicationModule(this)); 
    } 

    public void inject(Object object) { 
    graph.inject(object); 
    } 
} 

还有其他的方法来构建这个 - 你可以只是ApplicationModule包括AuthModule和声明注入,所以你只有两个模块,我这样建议,因为ApplicationModule是一个单独的问题,它的唯一作用是将Application实例提升到图中,AuthManagementModul专门用于支持auth函数,并且EntryPointsModule在那里成为整个图表的前面。

如果您迁移到Dagger2,则此结构也很方便,因为EntryPointsModule自然会转换为@Component。

+0

非常感谢! – Marko 2014-11-24 13:10:58

相关问题