2014-11-06 88 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

相關問題