2015-05-29 22 views
5

Chỉ mới bắt đầu sử dụng Dagger 2 hôm nay và tôi hơi bối rối về cách chính xác tôi cần thiết lập mọi thứ.Android Dagger 2 POJO field Tiêm null

Tôi đang cố gắng tiêm POJO nhưng nó luôn là rỗng. Thứ nhất, một số mã:

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(); 
} 

Tôi đã dành rất nhiều thời gian tìm kiếm thông qua rất nhiều hướng dẫn, SO các câu hỏi, và các ví dụ, nhưng tôi đã không thể tìm ra những gì tôi đang làm sai.

Tôi chắc chắn 99% tôi có thiết lập gì đó sai, nhưng tôi đã không thể tìm ra điều gì.

+0

Dường như bạn có chút nhầm lẫn. Mục tiêu của bạn là gì? Bạn đang cố gắng sử dụng 'NetworkingManager' ở đâu? – Emmanuel

+0

NetworkManager hiện là một singleton. Nó xử lý tất cả các mạng không đồng bộ. Nó được sử dụng khắp nơi. Mục tiêu của tôi là loại bỏ singleton và chuyển sang DI, cũng như làm cho lớp có thể kiểm chứng được. –

Trả lời

10

Dựa trên nhận xét của bạn, bạn muốn làm cho NetworkingManager khả dụng ở mọi nơi trong ứng dụng của bạn.

Hãy bắt đầu với định nghĩa của bạn của Component:

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

này cho Dagger mà thành phần này sẽ được tiêm lớp App. Bây giờ ở đây bạn cũng có thể nói với Dagger các lớp khác mà bạn muốn tiêm. Vì vậy, nếu bạn muốn cũng phải tiêm một Activity ví dụ bạn sẽ thêm:

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

Xin lưu ý rằng đây không phải là cách tốt nhất, IMO, chia sẻ phụ thuộc nhiều ứng dụng; bạn nên tạo một số Component được kế thừa từ AppComponent và tạo AppComponent hiển thị các phụ thuộc được chia sẻ mong muốn.

Bây giờ chúng ta hãy nhìn vào lớp mô-đun của bạn:

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

Ở đây bạn là @Provide ing một NetworkingManager, đó là tốt. NetworkingManager của bạn yêu cầu một số Application (thực tế là Context), tại sao không cung cấp App bên trong của NetworkingManager?, Hoặc thậm chí tốt hơn tại sao không cung cấp NetworkingManager bên trong AppModule từ AppModule nên @Provide những mục thông thường cho toàn bộ 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); 
    } 
} 

Bây giờ bên App lớp học của bạn:

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; 
} 
} 

Và trong chúng ta giả 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); 
    } 
} 

Có vẻ như bạn không sử dụng chính xác @Component(dependencies = {...}). dependencies được sử dụng khi bạn muốn hiển thị phụ thuộc từ một Component cho người khác sử dụng cơ chế tôi đã đề cập ở trên.

+0

Ok, điều đó có ý nghĩa hơn một chút. 1) Tôi giả định trong 'App.onCreate()' bạn có nghĩa '.build()' và không '.inject (this)', như 'inject()' trả về void. 2) 'NetworkingManager' nằm trong một gói khác với' App'. Tôi đã nghĩ rằng nó sẽ là tốt hơn để giữ module riêng biệt cho mỗi gói. Điều đó là không thể? 3) Bắt 'AppComponent' trong' MainActivity.onCreate() 'là tốt cho các hoạt động và phân đoạn. Điều gì về POJO không có quyền truy cập vào ngữ cảnh ứng dụng? Tôi có phải nhận được bối cảnh trong một hoạt động đầu tiên và chuyển nó đến POJO không? Điều đó có vẻ ngược về điểm DI với Dagger. –

+0

1) Bạn đã đúng, tôi đã sửa mã 'App'. Bạn sẽ gọi 'inject()' nếu bạn muốn tiêm 'App'. 2) Bạn chắc chắn có thể có các mô-đun khác nhau cho mỗi gói, nhưng tôi nghĩ rằng nó có ý nghĩa hơn để có các mô-đun khác nhau cho mỗi phạm vi (Mức ứng dụng, Cấp hoạt động, v.v.). 3) Đối với POJO, bạn có thể chỉ chú thích hàm tạo của chúng với '@ Inject' nếu chúng đang được sử dụng từ một lớp đã được' Component' tạo ra. Điều này có thể gây nhầm lẫn để nắm bắt. Chúng tôi có thể nói thêm về nó nếu bạn muốn ở trong phòng trò chuyện. – Emmanuel

Các vấn đề liên quan