Android:dagger2让你爱不释手-基础依赖注入框架篇
Android:dagger2让你爱不释手-重点概念讲解、融合篇
Android:dagger2让你爱不释手-终结篇

Dagger 2 完全解析(一),Dagger 2 的基本使用与原理
Dagger 2 完全解析(二),进阶使用 Lazy、Qualifier、Scope 等
Dagger 2 完全解析(三),Component 的组织关系与 SubComponent
Dagger 2 完全解析(四),Android 中使用 Dagger 2
Dagger 2 完全解析(五),Kotlin 中使用 Dagger 2
Dagger 2 完全解析(六),dagger.android 扩展库的使用

1、Component的使用

作为桥连接依赖和被依赖对象。
每一个Component都会创建一个对应的DaggerComponent
@Inject注解的构造函数会创建对应类的Factory,用于实例化该类

/** * 药物 */public class Medicine {    @Inject    public Medicine() {    }    public void treat() {        LogUtil.e("开始治疗");    }}
/** * 注射器 */@Componentpublic interface Injector {    //注射动作,指定病患    void inject(MainActivity mainActivity);}
/** * 病患 */public class MainActivity extends AppCompatActivity {    @Inject    Medicine mMedicine;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        //口服        Medicine medicine = new Medicine();        medicine.treat();        //打针        DaggerInjector.create().inject(this);        mMedicine.treat();    }}  

2、Module使用场景

1、没有构造函数
2、有参构造
3、三方库的类
每一个@Provides注解的方法都会创建一个Factory用来提供实例化对象给DaggerComponent使用。
@Provides注解的方法所需要的参数会优先从Module的其他provide中取。

@Modulepublic class ModuleClass {    @Provides    Gson provideGson() {        return new Gson();    }}
@Component(modules = ModuleClass.class)public interface ComponentClass {    void inject(MainActivity2 mainActivity);}
public class MainActivity2 extends AppCompatActivity {    @Inject    Gson mGson;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        DaggerComponentClass.create().inject(this);        String s = mGson.toJson(new Medicine());        LogUtil.e(s);    }}

3、@Scope作用域

@Scope是一个元注解,用于注解自定义注解,可以确定注入的实例的生命周期,并在声明周期内保持实例唯一。使用时Module 中 provide 方法中的 Scope 注解必须和 与之绑定的 Component 的 Scope 注解必须一样,否则作用域不同会导致编译时会报错。
作用域的原理,其实是让生成的依赖实例的生命周期与 Component 绑定,Scope 注解并不能保证生命周期,要想保证赖实例的生命周期,需要确保 Component 的生命周期。

@Singleton是通过@Scope定义的一个新的注解,能够使同一个Component中的对象保持唯一,保持唯一的条件是通过@Scope标记的注解相同。

@Singleton并没有创建单例的能力,起作用为
1、保证Component和Module是匹配的。
2、代码可读性。

以页面划分component,一个页面一个component,但这并不是一定的,有时候多页面会共用一个component,因为它们需要的参数一致。

一个全局component用来管理管理整个App的全局类实例。

@Scope //注明是Scope @Documented  //标记在文档 @Retention(RUNTIME)  // 运行时级别public @interface Singleton {}
@Modulepublic class FactoryModule {    @Provides    Gson provideGson() {        LogUtil.e("创建Gson对象");        return new Gson();    }}
@Component(modules = FactoryModule.class)public interface BridgeComponent {    Gson getGson();}
public class App extends Application {    public static BridgeComponent sBridgeComponent;    @Override    public void onCreate() {        super.onCreate();        sBridgeComponent = DaggerBridgeComponent.create();    }}
@Modulepublic class ActivityModule {    @Singleton    @Provides    Person5 providesPersonWithString() {        return new Person5("xls");    }}
@Singleton@Component(dependencies = BridgeComponent.class, modules = ActivityModule.class)public interface ActivityComponent {    void inject(MainActivity3 mainActivity);}
public class MainActivity3 extends AppCompatActivity {    @Inject    Person5 mPerson5;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        DaggerActivityComponent.builder().bridgeComponent(App.sBridgeComponent).activityModule(new ActivityModule()).build().inject(this);        Gson gson = App.sBridgeComponent.getGson();        LogUtil.e(gson.toJson(mPerson5));    }}

4、有参构造

MainModule -->providesPerson()中new Person(context)不能直接使用this.context,Module中查找返回Context的方法,并注入。此场景默认调用providesContext方法获取context。

public class Person {    public String name = "张三";    public int age = 23;    private Context context;    public Person(Context context) {        LogUtil.e("a person created with context:" + context);    }}
@Modulepublic class MainModule {    private Context context;    public MainModule(Context context) {        this.context = context;    }    @Provides    public Context providesContext() {        return this.context;    }    @Provides    public Person providesPerson(Context context) {        LogUtil.e("person from module");        return new Person(context);    }}
@Component(modules = MainModule.class)public interface MainComponent {    void inject(MainActivity4 mainActivity4);}
public class MainActivity4 extends AppCompatActivity {    @Inject    Person mPerson;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        DaggerMainComponent.builder().mainModule(new MainModule(getApplicationContext())).build().inject(this);        String s = App.getInstance().mGson.toJson(mPerson);        LogUtil.e(s);    }}

5、自定义标记、限定符

用于区分同类的不同依赖

public class Person5 {    public String name = "张三";    public int age = 23;    public Context context;    public Person5(Context context) {        this.context = context;        LogUtil.e("a person created with context:" + context);    }    public Person5(String name) {        this.name = name;        LogUtil.e("a person created with name:" + name);    }}
@Modulepublic class MainModule5 {    private Context context;    public MainModule5(Context context) {        this.context = context;    }    @Provides    public Context providesContext() {        return this.context;    }    //    @Named("context")    @PersonForContext    @Provides    public Person5 providesPersonWithContext(Context context) {        return new Person5(context);    }    //    @Named("string")    @PersonForName    @Provides    public Person5 providesPersonWithName() {        return new Person5("yxm");    }}
@Component(modules = MainModule5.class)public interface MainComponent5 {    void inject(MainActivity5 mainActivity5);}
public class MainActivity5 extends AppCompatActivity {    //    @Named("string")    @PersonForName    @Inject    Person5 p1;    //    @Named("context")    @PersonForContext    @Inject    Person5 p2;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        DaggerMainComponent5.builder().mainModule5(new MainModule5(getApplicationContext())).build().inject(this);        String s1 = App.getInstance().mGson.toJson(p1);        LogUtil.e(s1);        //java.lang.SecurityException: Can not make a java.lang.reflect.Method constructor accessible//        String s2 = App.getInstance().mGson.toJson(p2);//        LogUtil.e(s2);    }}
@Qualifier  // 关键词@Retention(RetentionPolicy.RUNTIME)  // 运行时仍可用public @interface PersonForContext {    // Context 对象的注解}
@Qualifier@Retention(RetentionPolicy.RUNTIME)public @interface PersonForName {    // name 对象的注解}

6、Provider、Lazy

沿用demo5部分文件

@Modulepublic class MainModule5 {    private Context context;    public MainModule5(Context context) {        this.context = context;    }    @Provides    public Context providesContext() {        return this.context;    }    //    @Named("context")    @PersonForContext    @Provides    public Person5 providesPersonWithContext(Context context) {        return new Person5(context);    }    //    @Named("string")    @PersonForName    @Singleton    @Provides    public Person5 providesPersonWithName() {        return new Person5("yxm");    }}
@Singleton@Component(modules = MainModule5.class)public interface MainComponent5 {    void inject(MainActivity5 mainActivity5);}
public class MainActivity5 extends AppCompatActivity {    //    @Named("string")    @PersonForName    @Inject    Person5 p1;    @PersonForName    @Inject    Provider providerPerson;    //    @Named("context")    @PersonForContext    @Inject    Lazy lazyPerson;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        DaggerMainComponent5.builder().mainModule5(new MainModule5(getApplicationContext())).build().inject(this);        Person5 person5 = lazyPerson.get();// 调用该方法时才会去创建Person,以后每次调用获取的是同一个对象        Person5 person6 = lazyPerson.get();        Person5 person7 = providerPerson.get();// 调用该方法时才回去创建Person1,以后每次调用都会重新加载Module中的具体方法,根据Module中的实现,可能相同,可能不相同。加@Singletom注解,创建一次        Person5 person8 = providerPerson.get();        String s1 = App.getInstance().mGson.toJson(p1);        LogUtil.e(s1);        //java.lang.SecurityException: Can not make a java.lang.reflect.Method constructor accessible//        String s2 = App.getInstance().mGson.toJson(p2);//        LogUtil.e(s2);    }}

总结

1、将实例化操作抽离出来,达到解耦的效果
2、单例无需考虑线程是否安全

更多相关文章

  1. Ubuntu adb devices : no permissions 解决方法
  2. Android 注解指南
  3. Android建立对话框基本的几种方法
  4. 2种自定义android标题栏titleBar的方法
  5. Android Environment 的作用以及常用的方法
  6. Android Studio 中方法数65536 或超过64K的解决方案
  7. Android SDK使用迅雷下载方法

随机推荐

  1. android中的spannable的使用(TextView分段
  2. android UI小结(五)
  3. Android 组件安全
  4. android - ViewPager 监听左右滑动
  5. Error: Error parsing D:\android-sdk-w
  6. OpenMax在Android上的实现
  7. android图形化学习1
  8. 认识Android手机--来自MIUI
  9. Android启动过程(转)
  10. NDK编译:fatal error: GLES2/gl2platform.