2017-02-28 53 views
1

嗨我已閱讀其他帖子,但我無法修復它。基本上我的問題是,我打電話.inject,當我想使用該字段仍然爲空。Dagger 2空場注入

我有這個類:

public class Application extends Game implements IApplication { 

    @Inject IApplication app; 
    @Inject IRouter router; 

    public Application(IPlatformCode platformCode) { 

    } 

    @Override 
    public void create() { 
     initDagger(); 
     System.out.println(app); //NULL 
     System.out.println(router); //NULL 
     router.showPage(Page.MenuPage); //NULL EXCEPTION 
    } 

    @Override 
    public void render() { 
     Gdx.gl.glClearColor(1, 0.5f, 1, 1); 
     Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); 
     super.render(); 
    } 

    @Override 
    public void setPage(IPage page) { 
     setScreen(page); 
    } 

    protected void initDagger() { 
     ApplicationComponent.Initializer.init(this).inject(this); 
     RouterComponent.Initializer.init().inject(this); 
    } 
} 

我不會讓路由器,因爲我做同樣的應用程序。

我的應用程序組件看起來是這樣的:

@Singleton 
@Component (modules = {ApplicationModule.class }) 
public interface ApplicationComponent { 
    void inject(IApplication application); 
    IApplication getApplication(); 
    static final class Initializer { 
     private Initializer(){} 
     public static ApplicationComponent init(IApplication app) { 
      return DaggerApplicationComponent 
        .builder() 
        .applicationModule(new ApplicationModule(app)) 
        .build(); 
     } 
    } 
} 

這是模塊:

@Module 
public class ApplicationModule { 
    private IApplication app; 

    public ApplicationModule(IApplication app) { 
     this.app = app; 
    } 

    @Provides 
    @Singleton 
    public IApplication providesApplication(){ 
     return app; 
    } 
} 

至於我打電話注入(IApplication)後讀取@Inject IApplication應注射和有一個值,但現在它是空的。

生成的代碼看起來是這樣的:提前

public final class DaggerApplicationComponent implements ApplicationComponent { 
    private Provider<IApplication> providesApplicationProvider; 

    private DaggerApplicationComponent(DaggerApplicationComponent.Builder builder) { 
     assert builder != null; 

     this.initialize(builder); 
    } 

    public static DaggerApplicationComponent.Builder builder() { 
     return new DaggerApplicationComponent.Builder(); 
    } 

    private void initialize(DaggerApplicationComponent.Builder builder) { 
     this.providesApplicationProvider = DoubleCheck.provider(ApplicationModule_ProvidesApplicationFactory.create(builder.applicationModule)); 
    } 

    public void inject(IApplication application) { 
     MembersInjectors.noOp().injectMembers(application); 
    } 

    public IApplication getApplication() { 
     return (IApplication)this.providesApplicationProvider.get(); 
    } 

    public static final class Builder { 
     private ApplicationModule applicationModule; 

     private Builder() { 
     } 

     public ApplicationComponent build() { 
      if(this.applicationModule == null) { 
       throw new IllegalStateException(ApplicationModule.class.getCanonicalName() + " must be set"); 
      } else { 
       return new DaggerApplicationComponent(this); 
      } 
     } 

     public DaggerApplicationComponent.Builder applicationModule(ApplicationModule applicationModule) { 
      this.applicationModule = (ApplicationModule)Preconditions.checkNotNull(applicationModule); 
      return this; 
     } 
    } 
} 

感謝。

+0

嘗試構建您的項目並查看由Dagger代碼生成的內容。 'app'真的注入了嗎? 'DaggerApplicationComponent'和'DaggerRouterComponent'是否正確生成? 'ApplicationComponent'是否真的從'ApplicationModule'提供'app'? – EgorD

+0

我沒有構建項目,所以DaggerApplicationComponent應該被正確構建。我將生成的代碼添加到帖子中,以防它幫助。 – mrk

+0

「RouterComponent」應該是「ApplicationComponent」的一個子組件嗎?我想你可能只有一個'@ Singleton'組件。 另一件我不清楚的事情,似乎是你將'ApplicationComponent'的init方法傳遞給'Application',只是爲了將同一個實例注入到它自己中。這僅僅是爲了測試,所有東西都連接起來了嗎? – benji

回答

1

你注射方法

void inject(IApplication application); 

需要改變,以

void inject(Application application); 

注意從IApplication只是應用的變化。你不能使用注入方法的接口,你需要使用一個類。

+0

是的,我意識到這是問題。我在之前的文章中評論過它。謝謝! – mrk

0

通常情況下,Dagger 2組件創建是在擴展Android應用程序類之一的類中完成的。這主要是爲了確保這些組件(以及它們所依賴的依賴關係)僅實例化一次。 (請參閱Dagger docs瞭解更多詳情:https://google.github.io/dagger/users-guide

雖然我還沒有看到任何說你不能用不同的方式連接它,但我還沒有找到它的一個例子。我想知道如果試圖通過Initializer.init()調用來即時連接組件,可能會繞過Dagger正確設置注入組件的能力。是否有可能將組件類的實例化重構爲一個Application實現?

上面的代碼看起來應該可以工作(除了每次使用init()調用而不是Singleton獲得新的DaggerApplicationComponent實例外),我無法真正解釋它爲什麼不能。

+0

問題是我想在那裏初始化其他的模塊,但我需要在那裏使用它來到另一個頁面。這就是我爲什麼這樣做的原因。在其他地方,我會很好地使用構造函數注入。到最後,initDagger只應該從create()中調用一次,它是入口點,永遠不會再調用。我不明白爲什麼我會實例化各種DaggerApplicationComponents – mrk

+1

請注意,這是LibGDX和Android .onCreate調用Application .create。 – mrk

+0

問題是我正在使用接口。例如,IRouter應該從模塊中返回新的Router(),但它沒有。顯然匕首並沒有分配這個權利。我切換到類而不是接口,它的工作。有什麼方法可以使用實例嗎?我喜歡這樣做,以防萬一我改變了實現方式,我可以改變模塊中的實例化,但在其他地方很好,因爲它需要一個IRouter。 – mrk