Hello!

I'm doing a test project with Dagger 2 .

What happened:

As I understand it, we need to do 3 things for this purpose:

  1. Create the @Module we @Module (in my example it is one), in which we block instances of the classes we need.
  2. Create an @Component class that will be a kind of root class for our modules. It is necessary to indicate the Activity that will use the dependencies of this component.
  3. You need to initialize AppCpmponent with the help of DaggerAppComponent and thereby build a dependency graph. (Slightly unusual, but this component is created at the stage of the first compilation - that is, if you start initializing it - the studio will simply not find this class. But after the first compilation, it will be available.)

What errors occurred:

I watched different manuals on this topic, almost the same scheme everywhere:

DaggerAppComponent initializes our AppComponent in a separate App class that inherits from Application . It is a little confusing why to inherit it from Application and initialize a separate class in OnCreate . Having done so, I had an error:

Caused by: java.lang.NullPointerException: Attempt to invoke interface method 'v.alexbykov.dagger.dagger.AppComponent.inject (ru.alexbykov.dagger.MainActivity)' on a null object reference at ru.alexbykov.dagger.MainActivity .onCreate (MainActivity.java:32)

Okay. I thought the point was that I initialized the DaggerAppComponent in the wrong place. (in the onCreate method of the App class. There was confidence that it is not called.

For the sake of the test, I decided to initialize it in a separate static method, which I then called into MainActivity - everything MainActivity out.

Question:

How to do it right in future projects when AppComponent initialized? Why in many manuals initialization occurs in the onCreate class inherited from Application ?


Project code, if anyone is interested:

Module:

 @Module public class DogModule { @Provides @NonNull @Singleton public Dog provideDog() { return new Dog("Pasha", 5); } } 

Component:

 @Component(modules = DogModule.class) @Singleton public interface AppComponent { void inject(MainActivity mainActivity); } 

App:

 public class App extends Application { public static AppComponent getComponent() { return DaggerAppComponent .builder() .dogModule(new DogModule()) .build(); } // @Override // public void onCreate() { // super.onCreate(); // component = buildComponent(); // } // // // protected AppComponent buildComponent() { // // // return DaggerAppComponent // .builder() // .dogModule(new DogModule()) // .build(); // } } 

MainActivity:

 public class MainActivity extends AppCompatActivity { @Inject Dog dog; TextView tw; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); App.getComponent().inject(this); tw = (TextView) findViewById(R.id.tw1); tw.setText(dog.getName()); } } 
  • is your App registered in the manifest? - ermak0ff
  • @ ermak0ff yes, it was not registered. Thank you) - no news

1 answer 1

In Application, it is initialized so that the component will be built exactly once, if you are sure that by creating it in the MainActivity methods it will not be initialized again, you can build it there.

In your code, it turns out that the component is created a new one each time, I suppose that with several injectors in the component, the code will not work as it should.

Here is the initialization snippet from my code:

 public class App extends Application { private static AppComponent component; public static AppComponent getComponent() { return component; } @Override public void onCreate() { super.onCreate(); component = buildComponent(); } protected AppComponent buildComponent() { return DaggerAppComponent.builder() .appModule(new AppModule(getApplicationContext())) .presenterModule(new PresenterModule()) .viewModule(new ViewModule()) .build(); } } 

In the manifest, do not forget to specify the name of the class that inherited from Application,:

 <application android:name="com.example.testapp.App" ... > ... 
  • Thanks for the answer! Only I have an error in this case. (Log in question), because App does not cause onCreate to fix this problem? - no news
  • Perhaps you didn’t specify the name of the class inherited from the Application in the manifest, added to the answer - MikkiMouse
  • thanks) now it has become much clearer) - no news