I have a module as follows.
@Module public class AppModule { private final Application app; public AppModule(Application app) { this.app = app; } @Provides @Architecture.ApplicationContext Context provideContext() { return app; } @Provides //scope is not necessary for parameters stored within the module public Context context() { return provideContext(); } @Singleton @Provides Application provideApp() { return app; } @Singleton @Provides SoundsRepository provideSoundsRepository(Context context, SoundsDAO soundsDAO) { return new SoundsRepository(context, soundsDAO); } }
A component like this.
@Singleton @Component(modules = AppModule.class) public interface AppComponent { void inject(Global global); void inject(MainActivity mainActivity); @Architecture.ApplicationContext Context getContext(); Application getApplication(); void inject(PostView postView); void inject(MediaPlayerService mediaPlayerService); }
In activity, fragment or service, I do this
@Inject SoundsRepository soundsRepository; @Override protected void onCreate(...) { //.... ((Global) getApplication()).getComponent().inject(this); }
In SoundsRepository
@Singleton public class SoundsRepository { @Inject public SoundsRepository(Context context, SoundsDAO soundsDAO) { this.context = context; this.soundsDAO = soundsDAO; System.out.println(TAG + "INIT"); } // .... }
So, now, every time I start to access an activity or service where SoundsRepository is injected, I get a new instance, I mean, the constructor of "SoundsRepository" fires again.
What am I doing wrong?
EDIT : Inject in Application Class
public class Global extends MultiDexApplication { protected AppComponent appComponent; private boolean calledAlready = false; @Override public void onCreate() { super.onCreate(); //if (LeakCanary.isInAnalyzerProcess(this)) return; //LeakCanary.install(this); initFirebasePersistance(); appComponent = DaggerAppComponent.builder().appModule(new AppModule(this)).build(); appComponent.inject(this); FrescoUtil.init(getApplicationContext()); } public AppComponent getComponent() { return appComponent; } }
1 Answers
Answers 1
- In your module you have a method that provides an instance of SoundsRepository - good
In your AppComponent you are missing a:
SoundsRepository soundsRepository();
In your
Global
which extends Application/MultidexApplication you create your DaggerAppComponent - goodIn your other activities/fragments/services just call:
Global application = (Global) getApplication(); SoundsRepository sr = application.getComponent().soundsRepository()
Android guarantees you have only one instance of your Application (Global) class for all other actvities/services (its somewhat like a singleton).
So keep your component in that application class, and whenever you need your class, call: (YourApplication) getApplication().getComponent().yourSingleInstanceSomething();
I created and tested sample code for you: https://github.com/zakrzak/StackDaggerTest
Dagger's @Singleton is just a scope, and does not guarantee returning a singular instance of a class.
In my understanding, if you:
void inject(PostView postView);
you tell Dagger to make everything you annotated with @Provided in AppModule accessible in your PostView as soon as you request it with:
@Inject SoundsRepository soundsRepository;
then dagger just calls the @provided method which in your case returns a new SoundRepository instance:
@Singleton @Provides SoundsRepository provideSoundsRepository(Context ........) { return new SoundsRepository(...); }
which causes your problem
0 comments:
Post a Comment