The field is not entered in the Android Dagger project

I play with Dagger on Android. I created a UserPreference model, a module called PreferenceModule and another UserPreferenceTest class, which is a PreferenceModule test. I have below 3 java files

UserPreference.java

 package com.sigicn.preference; import javax.inject.Inject; import com.sigicn.commonmodels.Application; public class UserPreference { public String name, weiboAccount; @Inject public Application[] frequentlyUsedApps; } 

Then PreferenceModule.java

 package com.sigicn.preference; import javax.inject.Singleton; import com.sigicn.commonmodels.Application; import com.sigicn.utils.MiscUtils; import dagger.Module; import dagger.Provides; @Module(library = true, complete = true) public class PreferenceModule { @Provides @Singleton UserPreference provideUserPreference() { UserPreference userPreference = new UserPreference(); userPreference.frequentlyUsedApps = provideApplications(); return userPreference; } @Provides @Singleton Application[] provideApplications() { return new Application[]{ new Application( MiscUtils.generateUUID(), "Youtube"), new Application( MiscUtils.generateUUID(), "Pixi") }; } } 

Then UserPreferenceTest.java

 package com.sigicn.test.preference; import javax.inject.Inject; import com.sigicn.preference.PreferenceModule; import com.sigicn.preference.UserPreference; import dagger.Module; import dagger.ObjectGraph; import android.test.AndroidTestCase; public class UserPreferenceTest extends AndroidTestCase { @Module(injects = {UserPreference.class, UserPreferenceTest.class}, includes = PreferenceModule.class) static class TestModule { } ObjectGraph objectGraph; @Inject UserPreference userPreference; @Override protected void setUp() throws Exception { if (objectGraph == null) { objectGraph = ObjectGraph.create(new TestModule()); } super.setUp(); } public void testFrequentlyUsedApps() { UserPreference localUserPreference = objectGraph.get(UserPreference.class); assertNotNull(localUserPreference); assertEquals(localUserPreference.frequentlyUsedApps.length, 2); objectGraph.inject(this); assertNotNull(userPreference); assertEquals(userPreference.frequentlyUsedApps.length, 2); assertSame(localUserPreference, userPreference); assertSame(localUserPreference.frequentlyUsedApps, userPreference.frequentlyUsedApps); } } 

But I don’t know why frequentlyUsedApps UserPreference not entered as expected. Any idea why?

Update:

I think I figured out the reason. This is because I manually create a UserPreference and use it in the provider. If I remove the Provider for UserPreference , and let Kinger connect it automatically, then the frequentlyUsedApps field will be entered. So it’s my fault that I don’t understand the dagger.

+5
source share
1 answer

I think you need to add some injection calls to ObjectGraph #.

In each class where you have the @Inject annotation, you will also need to call the input method of the ObjectGraph that you created.

I also struggled with this for a while. I think the main template is:

  • Annotate your fields to indicate that you want to enter them
  • Create a module to "provide" instances for these @Injects
  • Create a graph somewhere (most people seem to do this in the Application class)
  • In the classes you want to enter from your module, get an instance of the graph and call inject (this).

I started using a singleton, not the Application class, because at least for the moment I have some places that I have to add to the application myself.

So, here is what I am doing now, that seems to work pretty weill

 public class Injector { private static Injector mInjector; private ObjectGraph mObjectGraph; private MyApp mApp; private Injector() { } public static Injector getInstance() { if (mInjector == null) { mInjector = new Injector(); } return mInjector; } protected List<Object> getModules() { return Arrays.asList( new ApplicationModule(mApp), new AndroidModule(mApp) ); } public void inject(Object object) { getObjectGraph().inject(object); } public ObjectGraph getObjectGraph() { return mObjectGraph; } public void initialize(MyApp app) { mApp = app; mObjectGraph = ObjectGraph.create(getModules().toArray()); System.out.println(String.format("init object graph = %s",mObjectGraph.toString())); } } 

Then in my application class I have a constructor like this:

 public MyApp() { System.out.println("myapp construtor"); Injector.getInstance().initialize(this); Injector.getInstance().inject(this); } 

Then when I want to add something, I do it

 @Inject Bus mBus; public GcmBroadcastReceiver() { Injector.getInstance().inject(this); } 

I have two modules: one for production and one for testing.

Manufacturing has this

 @Provides @Singleton public Bus provideBus () { return BusProvider.getInstance(); } 

and test has this

 @Provides @Singleton public Bus provideBus () { return mock(Bus.class); } 
+7
source

Source: https://habr.com/ru/post/1200580/


All Articles