2015-05-29 76 views
5

今天剛開始使用Dagger 2,對於我需要如何設置所有東西,我有點困惑。Android Dagger 2 POJO字段注入null

我想注入一個POJO,但它總是空的。 首先,一些代碼:

App.java

private AppComponent appComponent; 

@Override 
public void onCreate() { 
    super.onCreate(); 
    appComponent = DaggerAppComponent 
      .builder() 
      .appModule(new AppModule(this)) 
      .build(); 
} 

public AppComponent component() { 
    return appComponent; 
} 

AppModule.java

@Module 
public class AppModule { 
    private Application app; 

    public AppModule(Application app) { 
     this.app = app; 
    } 

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

AppComponent.java

@Singleton 
@Component(modules = AppModule.class) 
public interface AppComponent { 
    void inject(App application); 
    Application application(); 
} 

NetworkingManager.java

@Singleton 
public class NetworkingManager { 
    private Context ctx; 

    @Inject 
    public NetworkingManager(Context context) { 
     this.ctx = context; 
    } 
} 

NetModule.java

@Module 
public class NetModule { 
    @Provides @Singleton 
    public NetworkingManager provideNetworkingManager(Application application) { 
     return new NetworkingManager(application); 
    } 
} 

NetComponent.java

@Singleton 
@Component(modules = {NetModule.class}, 
     dependencies = {AppModule.class}) 
public interface NetComponent { 
    void inject(NetworkingManager networkingManager); 
} 

SomeClass.java

@Inject 
NetworkingManager networkingManager; 

public void doSomethingWithNetworkManager() { 
    networkManager.doStuff(); 
} 

我花了很多時間一個很好的協議希望通過很多的教程SO,問題和例子,但我一直無法弄清楚我做錯了什麼。

我99%肯定我有東西安裝錯誤,但我一直無法弄清楚什麼。

+0

看來你有點混亂。你的目標是什麼?你想在哪裏使用'NetworkingManager'? – Emmanuel

+0

NetworkManager目前是單身人士。它處理所有的異步網絡。它被用在各地。我的目標是消除單身人士並切換到DI,並讓班級成爲可測試的。 –

回答

10

根據您的意見,您希望NetworkingManager在您的應用程序中隨處可用。

讓我們先從你的Component的定義:

@Singleton 
@Component(modules = AppModule.class) 
public interface AppComponent { 
    void inject(App application); 
} 

這告訴匕首,這個組件將被注入App類。現在你可以在這裏告訴Dagger你想要注入的其他課程。所以,如果你也想注入例如一個Activity你可以這樣:

@Singleton 
@Component(modules = AppModule.class) 
public interface AppComponent { 
    void inject(App application); 
    void inject(MainActivity activity) //Where MainActivity is a class that extends Activity. 
} 

請注意,這是不是最好的方式,國際海事組織,共享應用廣泛的依賴;您應該創建從AppComponent繼承的Component,並使AppComponent公開所需的共享依賴關係。

現在,讓我們看看你的模塊類:

@Module 
public class NetModule { 
    @Provides @Singleton 
    public NetworkingManager provideNetworkingManager(Application application) { 
     return new NetworkingManager(application); 
    } 
} 

給你@Provide荷蘭國際集團一NetworkingManager,這很好。您的NetworkingManager需要Application(真的是Context),爲什麼不在NetworkingManager裏面提供App?,甚至更好,爲什麼不提供NetworkingManagerAppModule因爲AppModule應該@Provide的事情,整個Application是常見的內部:

@Module 
public class AppModule { 
    private Application app; 

    public AppModule(Application app) { 
     this.app = app; 
    } 

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

    @Provides @Singleton 
    public NetworkingManager provideNetworkingManager(Application application) { 
     return new NetworkingManager(application); 
    } 
} 

現在你App類中:

public class App extends Application { 
    private AppComponent appComponent; 

@Override 
public void onCreate() { 
    super.onCreate(); 
    appComponent = DaggerAppComponent 
      .builder() 
      .appModule(new AppModule(this)) 
      .build(); 
    appComponent.inject(this); 
} 

public AppComponent component() { 
    return appComponent; 
} 
} 

而在我們的假設MainActivity

public class MainActivity extends Activity { 

private AppComponent appComponent; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    appComponent = ((App)getApplicationContext()).getAppComponent(); 
    appComponent.inject(this); 
    } 
} 

看來,您沒有正確使用@Component(dependencies = {...})。當您想使用上述機制將依賴從一個Component公開給另一個時,使用dependencies

+0

好的,這樣做更有意義。 1)我在'App.onCreate()'中假設'.build()'而不是'.inject(this)',因爲'inject()'返回void。 2)「NetworkingManager」與「App」不同。我認爲最好爲每個軟件包保留獨立的模塊。這不可能嗎? 3)在MainActivity.onCreate()中獲得'AppComponent'對於活動和片段是沒問題的。那些無法訪問應用程序上下文的POJO呢?我是否必須首先在活動中獲取上下文並將其傳遞給POJO?這似乎是DI與Dagger的關係。 –

+0

1)你說得對,我修復了'App'的代碼。如果你想注入'App',你可以調用'inject()'。 2)每個軟件包肯定有不同的模塊,但我認爲每個範圍有不同的模塊(應用程序級別,活動級別等)更有意義。 3)對於POJO,如果正在使用已經由'Component'注入的類使用它們,則可以使用'@ Inject'註釋它們的構造函數。這可能會讓人困惑。如果你想在聊天室裏聊聊,我們可以多談一談。 – Emmanuel