Dagger is a dependency injection framework for the android platform. It is a library launched by Square, a company focusing on mobile payment.
Other commonly used libraries in Android development: otto, okhttp, and retrofit. These will be described in the following blog.
In addition to the introduction of the official documents, I think the following analysis is quite good. Maybe you can see this when you are not familiar with Dagger.
If you write content, you will feel that you have no idea what to say. Based on your experience, it is recommended that you first understand the usage of Dagger and then see that this will have a better effect on understanding Dagger.
Next, let's go to the topic and give an example. Like the official example, I also use the example of coffee, but the official example is used in Java.
Android development is used in this example, and it is also improved.
First, let me explain this process. Since coffee is made, it is necessary to use a Heater. After heating, there must be a Pump process before it can be provided to people.
Drink ). With such a simple logic, you may feel as difficult as I was at the beginning, and very little code can be done. Yes, we need to use
A simple event to see how Dagger is implemented.
First, we will design the three interfaces Heater, Pump, and Drink, as shown below:
Package com. example. app. dagger;/*** Created by zjb on 14-1-22. */interface Heater {void on (); // enable void off () for the Heater; // disable boolean isHot () for the Heater; // whether the heating is complete}
Package com. example. app. dagger;/*** Created by zjb on 14-1-22. */interface Pump {void pump (); // inverted coffee boolean isPumped (); // whether it is good}
Package com. example. app. dagger;/*** Created by zjb on 14-1-22. */interface Drink {void drink (); // coffee}
OK, the interface has been designed, and whether it is reasonable for the moment is not detailed. Next we will implement these three interfaces respectively (useful to the AndroidAnnotations framework (please refer to the previous blog )):
package com.example.app.dagger;import android.content.Context;import android.widget.Toast;import org.androidannotations.annotations.EBean;import org.androidannotations.annotations.RootContext;import org.androidannotations.annotations.UiThread;/** * Created by zjb on 14-1-22. */@EBeanclass ElectricHeater implements Heater { boolean heating = false; @RootContext Context context; @Override public void on() { heating = true; System.out.println(-----Heating-----); reportHeating(); } @UiThread void reportHeating(){ Toast.makeText(context,Electric heater heating.....,Toast.LENGTH_LONG).show(); } @Override public void off() { heating = false; } @Override public boolean isHot() { return heating; }}
ElectricHeater is an implementation class for the Heater interface. @ EBean, @ RootContext, and @ UiThread are annotations in the AndroidAnnotations framework.
The @ EBean annotation will generate a ElectricHeater subclass ElectricHeater _. class during compilation, which will be used later.
Pump interface implementation:
package com.example.app.dagger;import javax.inject.Inject;/** * Created by zjb on 14-1-22. */class Thermosiphon implements Pump { private final Heater heater; boolean pumped = false; @Inject Thermosiphon(Heater heater) { this.heater = heater; } @Override public void pump() { if (heater.isHot()) { System.out.println(-----Pumping-----); pumped = true; try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } @Override public boolean isPumped() { return pumped; }}
package com.example.app.dagger;import javax.inject.Inject;/** * Created by zjb on 14-1-22. */class PeopleDrink implements Drink { private Pump pump; @Inject PeopleDrink(Pump pump) { this.pump = pump; } @Override public void drink(){ if(pump.isPumped()){ System.out.println(-----Drinking-----); } try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } }}
The three interfaces have been implemented. Have you found anything in common with the three implementation classes? Yes, you will find that @ Inject is used for annotation in the three classes.
Their constructor is because Dagger uses @ Inject to annotate an instance constructor of the class. When requesting a new instance, Dagger will obtain this
Parameter Value and call this constructor. Maybe you don't understand. It doesn't matter. Let's go on and explain it in detail.
Dagger can not only annotate the constructor like the above Code, but also directly annotate fields (Dagger can inject fields directly) to see this class:
package com.example.app.dagger;import javax.inject.Inject;import dagger.Lazy;/** * Created by zjb on 14-1-22. */class CoffeeMaker { @Inject Lazy
heater; @Inject Pump pump; @Inject Drink drink; public void brew() { heater.get().on(); pump.pump(); System.out.println(-----Pumped-----); heater.get().off(); drink.drink(); }}
By injecting Heater, Pump, and Drink into CoffeeMaker classes, you can directly use and call the method. It is worth noting that Dagger
The @ Provides method in @ Module is used to call the constructor to obtain the Instance Object (as described below ). If you do not @ Inject fields
Constructor: Dagger uses an existing non-argument constructor. If there is no @ Inject constructor, an error occurs. Continue reading @ Module
package com.example.app.dagger;import android.content.Context;import javax.inject.Singleton;import dagger.Module;import dagger.Provides;/** * Created by zjb on 14-1-22. */@Module(injects={CoffeeActivity_.class},library = true,complete = false)/*@Module(injects = {CoffeeActivity_.class},includes = {PumpModule.class,DrinkModule.class},library = true,complete = false)*/class DripCoffeeModule { private final Context context; public DripCoffeeModule(Context context) { this.context = context.getApplicationContext(); } @Provides @Singleton Context appliactionContext() { return context; } @Provides @Singleton Heater provideHeater(){ return ElectricHeater_.getInstance_(appliactionContext()); } @Provides @Singleton Drink provideDrink(PeopleDrink drink){ return drink; } @Provides @Singleton Pump providePump(Thermosiphon pump){ return pump; }}
The above is the class annotated with @ Module. Dagger requires that all @ Provides must belong to a Module. They are just a class annotated with @ Module.
Explain the previous sentence: If @ Inject implements injection, @ Provides implements dependency. @ Provides defines the return type of the method.
Dependencies. You may have noticed the @ Module I commented out. What does this mean? Yes. If I delete the providesDrink method, I can
Create another DrinkModule. java file. Because all @ Provides must belong to one Module, the DrinkModule class must come in:
package com.example.app.dagger;import dagger.Module;/** * Created by zjb on 14-1-22. */@Module(library = true,complete = false)public class DrinkModule { @Provides @Singleton Drink provideDrink(PeopleDrink drink){ return drink; }}
(What does the library and complete after @ Module mean? I will not mention it here)
So far, all three important annotations in Dagger have been involved. How does it manage these dependencies? Continue to look down:
package com.example.app.dagger;import android.app.Application;import org.androidannotations.annotations.EApplication;import dagger.ObjectGraph;/** * Created by zjb on 14-1-22. */@EApplicationpublic class CoffeeApplication extends Application { private ObjectGraph objectGraph; @Override public void onCreate() { super.onCreate(); objectGraph = ObjectGraph.create(new DripCoffeeModule(this)); } public ObjectGraph getObjectGraph() { return objectGraph; }}
As mentioned above, Dagger manages or organizes dependencies through ObjectGraph ).
The final main program: trigger the entire process with a button in the Section
package com.example.app.dagger;import android.app.Activity;import android.widget.Toast;import com.example.app.R;import org.androidannotations.annotations.AfterInject;import org.androidannotations.annotations.App;import org.androidannotations.annotations.Background;import org.androidannotations.annotations.Click;import org.androidannotations.annotations.EActivity;import org.androidannotations.annotations.UiThread;import javax.inject.Inject;import dagger.ObjectGraph;/** * Created by zjb on 14-1-22. */@EActivity(R.layout.coffee)public class CoffeeActivity extends Activity { @App CoffeeApplication coffeeApplication; @Inject CoffeeMaker maker; @AfterInject void daggerInject(){ ObjectGraph objectGraph = coffeeApplication.getObjectGraph(); objectGraph.inject(this); } @Click(R.id.coffeeClick) @Background void coffeeClicked(){ maker.brew(); coffeeBrew(); } @UiThread void coffeeBrew(){ Toast.makeText(this,Coffee has been pumped...,Toast.LENGTH_LONG).show(); }}
Running result:
com.example.app I/System.out﹕ -----Heating-----com.example.app I/System.out﹕ -----Pumping-----com.example.app I/System.out﹕ -----Pumped-----com.example.app I/System.out﹕ -----Drinking-----
With Dagger, we can implement dependencies well, and we can also clearly see that our code is doing something, so that we can clearly display
The logical relationship is shown in the following figure. each step of the logical relationship is displayed:
Well, Dagger will introduce it here. The source code will not be uploaded this time. After Otto is introduced, I will take the time to upload it to resources for you to download and learn.
Please forgive me for your reference. If you are interested in using dagger, you are welcome to discuss and learn it together. This is the last article before the Spring Festival.
Grab a good ticket and get the money right away!
Note: The Source of the original article is CSDN.Growth history of cainiao
Appendix:
Download resources from the Dagger ppt file of Jake Warhton