purcha
purcha

Reputation: 371

Objects after inject is null

I am trying to inject objects that are singletons to 2 activity.
My problem is, Milk and Coffee object after @Inject are null into Activity. In my opinion I miss something.
Please help me and tell me what is missing in the code

AppComponent:

@Singleton
@Component(modules = {CoffeeModule.class, MilkModule.class})
public interface AppComponent {

    @Component.Builder
    interface Builder {
        @BindsInstance
        Builder appModule(MyMvpApp myMvpApp);

        AppComponent build();

    }
    void inject(MyMvpApp app);
}

CoffeeModule:

@Module
public class CoffeeModule {

    @Provides
    @Singleton
    Coffee getCoffee(){
        return new Coffee();
    }

}

MilkModule:

@Module
public class MilkModule {

    @Provides
    @Singleton
    Milk getMilk(){
        return new Milk();
    }

}

My class App:

public class MyMvpApp extends Application{

    @Override
    public void onCreate() {
        super.onCreate();
        initDagger();
    }

    private void initDagger() {
        AppComponent appComponent = DaggerAppComponent.builder()
                .appModule(this)
                .build();
        appComponent.inject(this);
    }

}

And my Activity on which these objects are null:

public class LoginActivity extends AppCompatActivity {

    @Inject
    Milk milk;

    @Inject
    Coffee coffee;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_login);
        Log.i("tag", "" + milk + coffee);
    }
}

Upvotes: 0

Views: 97

Answers (2)

Ajay Chauhan
Ajay Chauhan

Reputation: 1551

You have to add two more lines inside your AppComponent class.

void inject(MyMvpApp app);

//you need to provide milk and coffee here
Milk getMilk();
Coffee getCoffee();

Edit 1 : one more thing you need to inject your activity too in the app component.

void inject(LoginActivity loginActivity);

and call the initDagger method in the activity in the same way you are doing in your Application class.

Edit 2 :If you dont want to repeat the whole thing,then create one method in your application class like this:

 private AppComponent appComponent ;

 public AppComponent getAppComponent(){
  if (appComponent == null) {
        appComponent = DaggerAppComponent.builder()
            .appModule(this)
            .build();
    }
    return appComponent;
}

 public void initDagger(){
  appComponent.inject(this);
}

Inside onCreate of Application class, call these methods.

getAppComponent();
initDagger();

Inside your activity, you can do like this rather than initializing the whole module again and again.

public void initDagger(){
getApplication().getAppCompoment().inject(this);
}

Upvotes: 1

ashishdhiman2007
ashishdhiman2007

Reputation: 817

@Singleton
@Component(modules = {CoffeeModule.class, MilkModule.class})
public interface AppComponent {

  void inject(LoginActivity app);

  @Component.Builder
  interface Builder {
    @BindsInstance
    Builder appModule(MyMvpApp myMvpApp);

    AppComponent build();
  }
}



public class LoginActivity extends AppCompatActivity {
  @Inject
  Milk milk;

  @Inject
  Coffee coffee;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    DaggerAppComponent.builder().appModule((MyMvpApp) getApplicationContext()).build().inject(this);
    Log.i("tag", "" + milk + coffee);
  }
}


public class MyMvpApp extends Application {

  @Override
  public void onCreate() {
    super.onCreate();
    initDagger();
  }

  private void initDagger() {
    AppComponent appComponent = DaggerAppComponent.builder()
        .appModule(this)
        .build();
  }
}

Upvotes: 1

Related Questions