Android Dagger 2 POJO字段注入null [英] Android Dagger 2 POJO field Inject null

查看:65
本文介绍了Android Dagger 2 POJO字段注入null的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

今天刚开始使用Dagger 2,我对我到底该如何设置一切感到有些困惑。



我正在尝试注入POJO,但它始终为空。
首先,输入一些代码:



App.java

 私有AppComponent appComponent; 

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

public AppComponent component(){
return appComponent;
}

AppModule.java

  @Module 
公共类AppModule {
私人应用程序应用;

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

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

AppComponent.java

  @Singleton 
@Component(modules = AppModule.class)
公共接口AppComponent {
void inject(App application);
Application application();
}

NetworkingManager.java

  @Singleton 
公共类NetworkingManager {
private Context ctx;

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

NetModule.java

  @Module 
公共类NetModule {
@ Provides @Singleton
public NetworkingManager ProvideNetworkingManager(Application application){
返回新的NetworkingManager(application);
}
}

NetComponent.java

  @Singleton 
@Component(模块= {NetModule.class},
依赖关系= {AppModule.class})
public接口NetComponent {
void inject(NetworkingManagernetworkingManager);
}

SomeClass.java

  @注入
NetworkingManagernetworkingManager;

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

我花了很多时间浏览许多教程,因此问题和示例,但我一直无法弄清楚我在做什么错。



我有99%的把握确定自己的设置有误,但是我无法弄清楚是什么。

解决方案

根据您的评论,您希望将 NetworkingManager 在您的应用程序中随处可见。



让我们从定义 Component :

  @Singleton 
@Component(modules = AppModule.class)
公共接口AppComponent {
无效注入(应用程序应用);
}

这告诉Dagger该组件将注入 App 类。现在,在这里您还可以告诉Dagger您想要注入的其他类。因此,例如,如果您还要注入 Activity ,则可以添加:

  @Singleton 
@Component(modules = AppModule.class)
公共接口AppComponent {
void inject(App application);
void inject(MainActivity activity)//其中MainActivity是扩展Activity的类。
}

请注意,这不是共享应用程序范围的最佳方法,IMO依赖您应该创建一个从 AppComponent 继承的 Component 并制作 AppComponent 公开所需的共享依赖项。



现在让我们看一下您的模块类:

  @Module 
公共类NetModule {
@Provides @Singleton
public NetworkingManager ProvideNetworkingManager(Application application){
return new NetworkingManager(application);
}
}

这里您是 @Provide 使用 NetworkingManager ,就可以了。您的 NetworkingManager 需要一个应用程序(实际上是 Context ),为什么不在 NetworkingManager 内提供 App ?甚至更好的是为什么不提供 NetworkingManager AppModule 内的code>,因为 AppModule 应该 @Provide 整个 Application 的共同点:

  @Module 
公共类AppModule {
私人应用程序应用;

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 类:

 公共类App扩展了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中

 公共类MainActivity扩展了Activity {

private AppComponent appComponent;

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

似乎您没有使用 @Component(dependencies = {...})正确。 dependencies 用于当您要使用我上面提到的机制将一个 Component 到另一个的依赖关系公开时。

Just started using Dagger 2 today and I'm a bit confused on how exactly I need to set everything up.

I'm trying to inject a POJO, but it's always null. First, some code:

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

I've spent a good deal of time looking through lots of tutorials, SO questions, and examples, but I haven't been able to figure out what I'm doing wrong.

I'm 99% certain I have something setup wrong, but I haven't been able to figure out what.

解决方案

Based on your comment, you want to make NetworkingManager available everywhere in your application.

Let's start with your definition of the Component:

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

This tells Dagger that this component will be injecting the App class. Now here you can also tell Dagger other classes you would like to inject. So if you want to also inject an Activity for example you would add:

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

Please note that this is not the best way, IMO, to share Application wide dependencies; you should create a Component that inherits from AppComponent and make AppComponent expose the desired shared dependencies.

Now let's look at your module class:

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

Here you are @Provideing a NetworkingManager, that is fine. Your NetworkingManager requires an Application (a Context really), why not provide App inside of NetworkingManager?, or even better why not provide NetworkingManager inside the AppModule since AppModule should @Provide things that are common for the whole 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);
    }
}

Now inside your App class:

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

And in our hypothetical 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);
   }
 }

It seems that you are not using @Component(dependencies = {...}) correctly. dependencies is used when you want to expose a dependency from one Component to another using the mechanism I mentioned above.

这篇关于Android Dagger 2 POJO字段注入null的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆