Dagger-Hilt in Detail - Full Course

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hey guys welcome back to a new video so in this video i thought i will talk a little bit about dagger hilt because i get so many questions um if i can make a tutorial about dagger hilt itself so essentially i already used it in some of my project tutorials which are perfect to learn dagger hilt but if you want to get a general overview of it first then this is the right video for you so here in this video i will really explain 95 percent of what you will need all the time with dagger healed so you can immediately use it in your projects right after this video but still i recommend to watch my project tutorials so that you get feeling for how you can actually use dagger healed in a practical project and not just um in a theoretical environment like we have it here so first we want to paste the dependencies for that you will find these in the github repository in this video's description so we'll just paste these here then we will need to also paste these two plugins here on the one hand for dagger hill itself and on the other hand cotton cap so kotlin annotation processing and to make sure that we don't get an error here with this plugin we need to also open up our build.gradle project file and paste this class path so simply go to my github repository and paste these three things i guess yes so then we can sync our project and by the way i also get the question a lot if you should use dagger hilt or the real dagger and i would say in pretty much all cases it is fine to use dagger hilt if you have a really big and really complex project it can make sense to use the old dagger the real the real dagger he'll just build on top of and because you just have a little bit of more um a little bit more freedom there but in general you can do so much with hilt and it's extremely easy in combination in comparison to the old dagger so first things first we want to create an application class when we use hilt you always need to do that because so let's first do that right click new kotlin class and call that my application it's like class because hild of course somehow needs to set up a lot of classes behind the scenes for us and for that hild also needs to know where our application class is it needs to have access to the application context in case we need that to construct one of our dependencies by the way if you don't know what dependency injection actually is then i recommend to watch this video first where i explain that in a very short amount of time i think two minutes so in this video i will really only explain health and not dependency injection in general but anyways um hilt just needs to know where our application class is so it can generate some classes behind the scenes for us we need to let that class inherit from application of course and the only thing we really need to do here with hilt is we need to annotate that with add field android app and that is everything we need to do to make hill generate these necessary classes here for our application and if you are a little bit familiar with android development then you know that we also need to declare that application class in our manifests file let's open that and specify the name property and just pass my application here okay and now that is enough to be able to inject dependencies with dagger healed but of course we need dependencies to inject to actually do that so for that we will actually create another class here new quadrant file class and this will be a so-called module so i will call this app module and why that is i will explain soon and that will be an object so with dagger hilt you usually declare one or multiple of these modules here and in these modules so these are basically containers for dependencies that live a specific amount of time so in this app module we will define all dependencies that just live as long as our application does so that could for example be a retrofit instance a room instance so just objects that we need throughout the whole lifetime of our application but with dagger hilt we also have the option to scope our dependencies so we cannot only have an app module with singleton dependencies we can also have for example a main activity module so a module that contains dependencies that only live as long as our main activity does and when we then switch the activity we can't um we can't inject those main activity dependencies anymore in another activity but you will see how that works so we select object here and with dagger hilt we always need to use a lot of annotations here also in these modules on the one hand just module to tell dagger hill hey this is a module and we also want to use add install in so as i said we want to scope these dependencies we declare in this module um and for that we need to tell daggerfield how we actually want to scope them so we need to tell it hey in this app module we want these dependencies to be alive as long as our application and that's what this install and annotation is for so we can say we install this in the application component which just tells dagger hilt hey these dependencies live as long as the application but there are also for example activity components so then these dependencies would only live as long as a specific activity there also uh whoops fragment component view component so to inject into a custom view and yeah you can play around with that i will just leave it as application component which you will need the most but it's also pretty common that you need a specific object only in one activity and then you should declare a separate module for that and use install in activity component or fragment component whatever now in this app module we need to give dagger hills somehow a blueprint how it can construct the dependencies that we want to inject so i will just use very simple examples here as i said in my project tutorials you will see how that works if you want to inject a room database if you want to inject a retrofit instance and so on but this would just be way too much for this single tutorial here so we will just inject simple strings we will declare these strings here in this app module and then inject these into our activity our main activity and we will also inject them into a viewmodel we will create so how can we do that we essentially only declare functions here in this module so we can declare a function and the naming convention for these functions in modules is always that we want to provide something we want to provide a specific dependency for other classes so we specify provide and what do we provide well a test string for example and in this function we return whatever we want to provide here and whatever we want to inject in our classes later so i'll set this equal to this is a string we will inject and also here we need two more annotations on the one hand at singleton well we don't need this but that's a very common annotation here that i need to show you um this add singleton annotation will well make this string a singleton so we will only have a single instance of this string if we wouldn't have this annotation then every time we inject the string it would create a new instance of it and it wouldn't reuse the old instance so usually you don't want this in some scenarios you you want to you want this but usually you have singletons for databases for retrofit singletons so you don't need to construct that object over and over again every time you inject it and another annotation we need is just add provides to tell daggerfield hey with this function we want to provide a dependency which is this string in our case so let's see how we can get this string now inside of our main activity um if we want to inject dependencies into android components such as activities fragments views and all that stuff then we also need a special annotation surprise surprise and that is at android entry point so every time you just want to inject something with daggerfield into an activity or fragment or view then you need this annotation otherwise your program will crash and also if you want to just inject something into a fragment then you need to annotate the fragment with this annotation but also the parent activity so that's a common case of crashes here but it will actually tell you what's wrong there so how can we now inject the string that we declared here in our app module into this activity well for that we just need to declare a latent variable call that whatever we want and make sure that as a string right now this variable if we would access this here so let's say we want to have a log statement there's a tag of main activity and just print test string from main activity and print this test string here if we would now simply launch our app then it would crash because this string is not initialized yet because it's a latent variable of course but what we can do now with daggerhild is we can annotate this with at inject and this will actually assign the the value of this latent variable behind the scenes for us so that when we launch our app we know the value of this test string and that is exactly this string here so what will actually happen behind the scenes is dagger hilt will see okay we want to inject a variable here or an object and that object is of type string and then it will just search in all of its modules here if it can find a string dependency and yes it can't find that so it can't find oh here is a dependency that is provided which is of type string so i will simply take this string and assign it to this variable and that's everything about it so now you have a central place here where you manage your dependencies you can easily define them as single turns and then you can simply inject them everywhere in your project and reuse them which will make your project a lot really a lot more structured and just so that you believe me let's actually run our app take a look your logcat and search for test string and you can see here it prints test string from main activity this is a string we will inject which is exactly this string here so now you might wonder what actually happens if we have two strings two string dependencies that we want to be able to inject how does dagger hill know which string it should actually inject here well the answer is it can't know that of course so let's actually see how that works let's copy this function place it down here so we declare another string dependency and let's call this this is a string we will inject as well all this provide test string 2 and provide test string 1 so this is essentially it doesn't matter how you call these functions that those are only for dagger hills so it knows how it can create these objects we want to inject but just for your understanding you should give these good names here let's say we have it like this so we provide two strings two different strings but we only inject this single string here in main activity if we now launch this app then you can see we get a bunch of errors here and it will open some strange classes that it generated for us that's not very helpful but the fix is luckily very easy and that is we can give these circle named annotation so we can just um give these dependencies a name so string one and we give this a named annotation of string two and then in our main activity we can also just as well declare the named annotation here and we want to inject string one so that's how you can manage it if you have multiple dependencies of the same type let's actually also quickly see how it works if we have such an activity module so with a string that only lives as long as our main activity so let's we can actually copy this app module and paste it call that main module because it's for our main activity swap sort this out with activity component and let's say here we will actually only provide the second dependency in our app module we will only provide the first dependency so that will be essentially a singleton and that will be a dependency a string that is only active as long as our main activity in this case if we have such an activity component this singleton annotation doesn't work because singleton is an annotation that only works in combination with application component so we can't have a singleton that only lives as long as our activity that doesn't make any sense but the equivalent to that is activity scoped so that just means hey we have this string that lives as long as our activity but we only have a single instance of this so if we inject this multiple times in the same activity there will only be a single instance it won't recreate that string over and over again and maybe you've also asked yourself how does it work if we actually need some other dependencies to construct this object here so let's say we actually want to inject this string but this string is actually from our string resources and to access our string resources we need the context and here in this main module we obviously don't have that context right now so let's actually do that we copy this string here go to our values folder strings.xml i'll duplicate that was not duplicate i will duplicate this string call that string to inject and simply paste this is a string we will inject as well so we now want to inject this string but we for that we need to access our strings xml file and for that we need the context how does that work let's take a look back in our main module so you can see here if we now want to access our string we usually use the getstring function but for that we actually need an a context object which we don't have here so essentially we simply put that context object here as a parameter so we use context colon context and then we can use that here but right now dagger hill still doesn't know from where it should get that context object the context here is actually a special thing with dagger hilt for that we need to annotate this with application context and then it will use the context it can get from our application class that we annotated here and everything will work fine so now we can access context.getstring.string string to inject and that will work fine so as i said this is kind of a special case here because we need this annotation to get the context but sometimes we also need dependencies we created before we provided before so let's say we we need this test string run here to actually construct our test string too so let's say we just put some string here together like this and then we a little minus and then we want to have our test string 2 here but how can we actually get this our test string one of course so that is the string we provided here in our app module but we don't have access to that in this provides function well then we can as well just define that here as a parameter so test string two also of type string um string one of course and then dagger hilt will inject that so it will figure out in which order it has to provide the dependencies so it can construct them the right way so dagger hill is smart enough to see okay i need this test string one for this test string two so i just create this test string one before this test string two and here i think we have the same problem as our remain activity we provide two strings so we need to add this named annotation here i'm not really sure in this case because we provide the second string here um but i think we need this so just write string one so it actually knows that we want this string here so you can see here we have the name annotation string one here as well so it will take this string and inject it or kind of replace it for this test string one and then it will use the context object as well to get the string from our string resources and also concatenate it with this test string one so that is something you need to do very often that you just need other dependencies to construct another dependency also for a room database you of course need the the application context so then you will also need to do this and as a last part of this video i will show you how we can inject dependencies into viewmodels because that works a little bit differently it isn't as easy as in activities so for us thanks to dagger hill it is but behind the scenes it's very difficult because for view models you need to inject the dependencies into the constructor and for that you need a viewmodel factory so that is just a special class that you need to declare and we actually don't want to do that with the old dagger we needed to do that that was complicated as hell but with hilt it actually does that for us so we still need to consider something let's first create our view model test view model uh inherits from viewmodel of course and now let's say we want to inject this test string2 in our viewmodel then we need to do that in the constructor and we need to annotate this constructor in view models with that view model inject and then specify constructor import and view model inject and here in this constructor we can now just specify the dependencies we want to have on this view model and thanks to this annotation daggerfield will create this viewmodel factory behind the scenes for us so here we will again specify named we want our string2 and if there's a name of test string 2 of tab string so here we don't need this inject annotation because we already have it for the constructor and normally you can also inject your dependencies into constructors just like we do it here but outside of your models you just use the normal inject annotation for that but viewmodels are kind of a special case here where you need viewmodel inject and then let's just print it in the init block log statement let's use a viewmodel tag and just print test string from your model and print out our test string 2. now that's at how we can inject dependencies into our view model now we also need to think about how we can inject our view model in our main activity because we of course need an instance of that here for that we have we don't use inject because of all that viewmodel factory stuff instead we will simply use a private valve call that viewer model we need to specify the type here we just test view model then we use cotton delegations so by view models that is a function that comes from this dependency here and this will make daggerfield just inject the viewmodel on the testview model it actually has into this variable and this will actually be a lazy initialization i think so if we don't actually access this viewmodel somewhere here it won't actually create it it won't go inside of this init block and print it so what we need to do is we can just use specified view model here that won't do anything but it will actually access this view model so it will be created and it will go inside of this init block so if we now launch our app then take a look here in logcat also have the search filter on you can now see our two strings were injected successfully on the one hand from our main activity our test string for main activity actually this one this is a string we will inject which comes from our app module and then we have the test string from our view model which is this log statement and this says this is a string we will inject as well which is here in our main module this comes from our string resources now then this little minus and this comes now from our test string one we actually declared in our app module here so just to show you how it works if we need multiple other dependencies to construct a new one and i know this now was a lot of new stuff as i said i really recommend to watch one of my project tutorials about dagger hilt or rather where i use it for example my running tracker app or the spotify clone and that will for sure make it much clearer for you and also if you want to see how you can use dagger hilt and just how you can make more advanced android projects then you should check out the first link in this video's description which will lead you to my website and there you will find more advanced premium courses which just go beyond what i teach here on youtube so you can take your android skills to the next level other than that thanks for everyone watching this far have a really nice day see you next video bye bye so
Info
Channel: Philipp Lackner
Views: 70,545
Rating: undefined out of 5
Keywords: android, tutorial, philip, philipp, filipp, filip, fillip, fillipp, phillipp, phillip, lackener, leckener, leckner, lackner, kotlin, mobile, hilt, dagger, dagger2, course
Id: ZE2Jkvnk2Bs
Channel Id: undefined
Length: 25min 42sec (1542 seconds)
Published: Wed Dec 30 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.