I have created a EmailComponent interface which has 2 modules EmailModule and Networkmodule , I am trying to share Email object and Okhttpclient object between activites . In ActivityA I did:
EmailComponent component = DaggerEmailComponent.builder()
.emailModule(new EmailModule())
.netWorkModule(new NetWorkModule()).build();
component.Email().sendEmail();
This is working fine. My question is how can I inject them into ActivityB Without calling again DaggerEmailComponent build code?
If i try using field injection in ActivityB like this code below it crashes.
#Inject Email email
email.sendMail(); // App crash.
Is what am trying to accomplish possible? If Yes, what am I doing wrong?
To avoid making the EamilComponent again and again you may make a Base Activity and move the code of making the component there. Or you may make a subclass of Application and make a static component there which can then be used from anywhere in the app. You must be getting NPE as the field may not have been initialized.
For using static component from the Application subclass create a method in your dagger component with your base activity as a parameter and then call that method using the static EamilComponent in Application subclass just after the onCreate of the activity. You can even call the method in the component before onCreate.
Related
I'm practicing dagger 2 for a week now, I just want to know the difference of these injections(constructor, method, field), and where should I use them.
Constructor: whenever you've the possibility to do so (when you have access to the constructor, for example, with your presenters if you use MVP pattern).
Field: when you don't have access to the constructor, for exemple when injecting in your Activity or Fragment.
Method: an #Inject annotated method will be executed by Dagger as soon as the construction call has finished. We usually use it when we want to pass class instance itself (this reference) to injected dependencies.
Read this for more informations and examples of use cases.
I've read a lot of posts and tutorials about dagger 2:
http://frogermcs.github.io/dependency-injection-with-dagger-2-custom-scopes/
https://github.com/codepath/android_guides/wiki/Dependency-Injection-with-Dagger-2
http://fernandocejas.com/2015/04/11/tasting-dagger-2-on-android/
https://github.com/konmik/konmik.github.io/wiki/Snorkeling-with-Dagger-2
What determines the lifecycle of a component (object graph) in Dagger 2?
etc.
But I am still confused about the lifecycle of a component, and how it relates to module and scope. I want to make sure I don't create multiple instances of an object when I only want a Singleton. Hope someone can shed some light on these:
What's the lifecycle of a component that's built in the application class?
What's the lifecycle of a component that's built in the Activity or Fragment class?
If I want a singleton instance from a component, do I must annotate the component with #Singleton or a custom made scope and build that component in the application class?
If I build a component in the application class, does that mean all the object instances available through this component will be a singleton instance throughout the app until the app is killed or restarted?
I have a component with a custom scope let's say #ActivityScope, and I build that component in an Activity, will the object instances injected through this component be destroyed automatically after this activity's onDestroy() is called?
Again I have a component with a custom scope let's say #ActivityScope, and I build this component in ActivityA and ActivityB, will ActivityA and ActivityB share the same object instances from this component or they will have their own instances of the same object?
How I understand it:
And keep in mind two things (when I first read 1) it it made everything cleaner to me):
1)Components live as long as you want it to or as long as class that created component wasn't destroyed (like android activity or fragment)
2)If you don't annotate you provide methods with annotation (must be the same as component annotation) new objects will be created every time you request for them
What's the lifecycle of a component that's built in the application class?
Component built in application class lives as long as you want. I mean you can create it at any time and remove it at any time as long as you create it in class that extends android Application class (this way component object will live as long as your Android App is running) in contrast to component that's built in activity class - it will live as long as activity is alive so it may be destroyed for example on orientation change.
Keep in mind that if for some reason you didn't create your ApplicationComponent in onCreate() method of Application class (for example you created it later when something happened) it can be destroyed (nulled) when Android OS is low on memory and user closed your app, and then when user comes back to your app (to last visible activity) when it has been killed earlier and you ask your app component to do something then check if it's not null
What's the lifecycle of a component that's built in the Activity or
Fragment class?
I partially answered it in above answer. If you create your component inside Fragment/Activity it lives as long as you want or as long as activity or fragment is not destroyed due to orientation change or low memory
If I want a singleton instance from a component, do I must annotate
the component with #Singleton or a custom made scope and build that
component in the application class?
It depends where you want to use this singleton. If you want singleton in single activity you may create for example #ActivityScope annotation and annotate provide methods and ActivityComponent with this annotation, then you create your ActivityComponent inside onCreate() Activity method and you have a singleton as long as your activity lives (it may be helpfull if you plan to have a singleton shared between different fragments from same activity).
If you want singleton between different acctivities/fragment in app the best way to do that would be to create it in AppModule and annotate provide method and app component with singleton annotation.
If I build a component in the application class, does that mean all
the object instances available through this component will be a
singleton instance throughout the app until the app is killed or
restarted?
If you annotate provide methods with #Singleton annotation then yes
I have a component with a custom scope let's say #ActivityScope, and I
build that component in an Activity, will the object instances
injected through this component be destroyed automatically after this
activity's onDestroy() is called?
Yes
Again I have a component with a custom scope let's say #ActivityScope,
and I build this component in ActivityA and ActivityB, will ActivityA
and ActivityB share the same object instances from this component or
they will have their own instances of the same object?
They will have their own instances
My Android app has multiple activities. The MainActivity constructs a Dagger2 component in its onCreate() method and assigns it to a static variable so any class can call the static method MainActivity.getDaggerComponent() to then inject itself with dependencies.
The problem I'm discovering is that when I start up my VideoPlayerActivity, the MainActivity object sometimes gets its onPause() invoked. If this happens, the static component variable gets set to null. At a later point, VideoPlayerActivity needs to inject its dependencies, but there is no component so things blow up.
How does one ensure that a Dagger2 component is available at all times for all activities?
Initialize Dagger component in Application class or just statically. It might be that you're doing a very wrong thing trying to use dependencies of one Activity in another Activity. This might create memory leaks and in particular sounds like a design problem. What if your first Activity was already destroyed? Who will free up the Dagger instance? Why graph belongs to first Activity and not to the second one? What if user will enter your app from the second Activity - then first one won't be even initialized. And so on, and so on.
If you still need Activity instance, then you should use Activity specific component within the Activity and move everything else in global (Application wide) component.
My activity contains a TabHost , and I implemented the constructor of the activity. At runtime the app crashed ! So I removed the implementation of the constructor and the app run successfully ! So why and when should we implement the constructor of an activity ?
In Android, Activities are initialised by the system through ClassLoader, who is requiring public non-argument constructor in order to initialise the object.
Normally, you never override/add constructor for activities in Android.
If really want to do it, however, you must implement public non-argument constructor.
Look at the documentation for more details how this class works:
Activity
So I'm trying to make an application using the Singleton Method. I want to have a class that stores all the information about my device's bluetooth state/connections/devices, and I want to make multiple activites that can access these methods.
I know that I need to have a class that extends Application, then I can access everything by calling getApplication(). What I do not understand, is where I initialize this object. From my frame of reference, I have all of these separate Activities, and if I initialize the object in one, I'm going to need to use intents to pass the object to the next activity, which completely defeats the purpose of using the singleton method.
Any help would be appreciated, thanks.
Simply extend from android.app.Application. Then register it as the application class in your AndroidManifest.xml:
<application android:name="mypackage.MyApplication" ...>
In your class you will receive usual Android calls, such as in
#Override
public void onCreate() { }
where you will able to initialize your global instances.
In the activities fetch the instance of MyApplication downcasting with:
MyApplication app = (MyApplication) getApplication();
Hope that helps.
If you extended Application your class will be created as your app launches. It can be retrieved in Activity classes using getApplication()
Check here : http://www.kodejava.org/examples/12.html
and here : http://www.devahead.com/blog/2011/06/extending-the-android-application-class-and-dealing-with-singleton/
and here : http://inchoo.net/mobile-development/android-development/android-global-variables/