dagger2的配置及基本使用(一)
来源:互联网 发布:封印者画质优化 编辑:程序博客网 时间:2024/05/17 16:44
一、配置:
1.1 在Project的gradle脚本中配置
dependencies { classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8' }
1.2在Module的gradle脚本中配置
apply plugin: 'com.neenbedankt.android-apt'dependencies {apt 'com.google.dagger:dagger-compiler:2.11' compile 'com.google.dagger:dagger:2.11' }
二、代码实现
2.1、使用@Inject和@Component实现依赖注入
2.1.1: 在实体类的构造方法中标注@Injecct,表示其提供依赖,代码如下:
package testdagger.com.xn.testdagger2.modle;import android.util.Log;import javax.inject.Inject;/** * Created by 贺谋昌 on 2017/8/1. */public class Watch { @Inject public Watch() { } public void work() { Log.e("Watch", "Dagger2 watch is work"); }}
2.1.2:创建注入器,即提供依赖和目标类之前的桥梁,是一个用@Conponent标注的接口
代码如下:
package testdagger.com.xn.testdagger2.component;import dagger.Component;import testdagger.com.xn.testdagger2.MainActivity;/** * Created by 贺谋昌 on 2017/8/1. */@Componentpublic interface MainActivityComponent { void inject(MainActivity activity);}
其创建的方法中传入的参数为目标类的实体
2.1.3
在目标类中进行注入,并标注依赖注入的实体类
public class MainActivity extends Activity { @BindView(R.id.btn) Button btn; @Inject Watch watch; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ButterKnife.bind(this); DaggerMainActivityComponent.create().inject(this); } @OnClick(R.id.btn) public void onViewClicked() { watch.work(); }}
DaggerMainActivityComponent这个类是在component类完成之后进行reBuild后自动生成的类。
2.2、使用@Module和@Provides提供依赖
如果代码中使用了第三方的类库,那么目标类所需的依赖是无法进行标注的,因为无法更改实体类的源代码,比如一个jar包,这时我们用@Module和@Provides提供依赖。
2.2.1、新建一个标注@Module的类,并通过标注@Provides的方法返回实体类的对象,代码如下:
/** * Created by 贺谋昌 on 2017/8/1. */@Modulepublic class GsonModule { @Provides public Gson getGson() { return new Gson(); }}
2.2.2、使用已经创建的component来管理Module,只要在类名处标注上管理的是哪个Module即可,代码如下:
** * Created by 贺谋昌 on 2017/8/1. */@Component(modules = GsonModule.class)public interface MainActivityComponent { void inject(MainActivity activity);}
2.2.3、在目标类中注入,并标注要使用的实体类,代码如下:
public class MainActivity extends Activity { @BindView(R.id.btn) Button btn; @Inject Watch watch; @Inject Gson gson; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ButterKnife.bind(this); DaggerMainActivityComponent.create().inject(this); } @OnClick(R.id.btn) public void onViewClicked() { watch.work(); JSONObject object = new JSONObject(); try { object.put("name", "贺贺"); object.put("age", 24); Man man = gson.fromJson(object.toString(), Man.class); Log.e("MainActivity", man.getName()); } catch (JSONException e) { e.printStackTrace(); } }}
2.3、如果要注入的对象是抽象的则不能用@Inject来提供依赖,这时要用@Module,案例如下:
Engine是一个抽象类
public abstract class Engine {public abstract String work();}
MyEngine是Engine的子类
public class MyEngine extends Engine { @Override public String work() { return "MyEngine is working"; }}
Car持有Engine的对象
public class Car { Engine engine; @Inject public Car(Engine engine) { this.engine = engine; } public String run() { return engine.work(); }}
2.3.1、在component中提供一个方法,给Engine提供实例
@Modulepublic class GsonModule { @Provides public Engine getEngine() { return new MyEngine(); }}
2.3.2在MainActivity中注入
@Inject Car car; ... DaggerMainActivityComponent.create().inject(this); .... Log.e("MainActivity", car.run() );
2.4、@Name和Qualifier的基本使用
如果@Inject标注的多个构造或是@Provides标注的方法返回的是同一种类型的值,那么程序就不知道使用哪一个来提供依赖,这时就会报错,我们就可以使用@Qualifier来标注我们要使用的是哪一个,@Name是@Qualifier的一种实现。案例如下:
如果Engine的子类有两个,除了MyEngine之外还有HerEngine,在Module中返回的Engine的实例的方法中,有两个方法,一个返回MyEngine一个返回HerEngine,这时我们就要标注好哪个方法返回哪个实例,并且目标类需要哪个实例,可以用@name(字符串)也可以自定义Qualifier,示例代码如下:
//首先定义两个自定义的Qualifier @Qualifier@Retention(RetentionPolicy.RUNTIME)public @interface My {}........@Qualifier@Retention(RetentionPolicy.RUNTIME)public @interface Her {}....//在Module中标注好,哪个方法对应的哪个类的实例 @Provides @My public Engine getEngine() { return new MyEngine(); } @Provides @Her public Engine getHerEngine() { return new HerEngine(); } // 标注好目标类需要哪个实例 public class Car { Engine engine; @Inject public Car(@Her Engine engine) { this.engine = engine; } public String run() { return engine.work(); }}
使用@Name来标注则更为简单
“`
@Provides
@Named(“My”)
public Engine getEngine() {
return new MyEngine();
}
@Provides@Named("Her")public Engine getHerEngine() { return new HerEngine();}//在需要依赖的类中同样使用@Name标注好public class Car {Engine engine;@Injectpublic Car(@Named("Her") Engine engine) { this.engine = engine;}public String run() { return engine.work();}
}
2.5、Dagger2实现单例模式
2.5.1、实现局部单例
在提供依赖的地方标注@Singleton
@Singleton @Provides public Gson getGson() { return new Gson(); }
在Module中标注@Singleton
@Singleton@Component(modules = GsonModule.class)public interface MainActivityComponent { void inject(MainActivity activity);}
//这样就完成了局部单例
2.5.2、使用@Scope实现全局单例模式
其实@Singleton是被@Scope标注的注解,@Scope标注实际上就是用来实现局部单例的,它的本质就是注解的注解,只要在想要实现某个类是单例模式,只需要在其提供依赖的地方标注被@Scope标注的注解,然后在其component中标注被@Scope标注的注解,上述@Singleton就是做了这样的操作。还有一个要注意的点就是component会每注入一次就实例化一次,所以我们只要让Component成为单例,就可以实现全局单例了。下面开始正式的实现:
新建一个被@Scope标注的注解
@Scope@Retention(RetentionPolicy.RUNTIME)public @interface ApplicationScope {}
首先在提供依赖处标注刚定义的注解@Modulepublic class GsonModule { @ApplicationScope @Provides public Gson getGson() { return new Gson(); }然后在提供依赖处和component处标注此注解@ApplicationScope@Component(modules = GsonModule.class)public interface MainActivityComponent { void inject(MainActivity activity); void inject(SecondActivity activity);}新建一个Application在onCreate中实例化component,这样就能保证该component只有一个实例public class MyApplication extends Application { MainActivityComponent component; @Override public void onCreate() { super.onCreate(); component = DaggerMainActivityComponent.create(); } public static MyApplication get(Context context) { return (MyApplication) context.getApplicationContext(); } public MainActivityComponent getComponent() { return component; }}在需要使用的地方,用实现单例的component进行注入即可,在这里我们分别在两个不同对的Activity中打印该类实例的HashCode,若是相同,就说明我们成功实现了单例.public class MainActivity extends Activity { @Inject Gson gson; @Inject Gson gson1; @BindView(R.id.jump) Button jump; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ButterKnife.bind(this); MyApplication.get(this).getComponent().inject(this); } @OnClick({R.id.btn}) public void onViewClicked() { Log.e("MainActivity", car.run()); Log.e("MainActivity", "gson:" + gson.hashCode() + " gson1" + gson1.hashCode()); }}在另一个Activity中我们做相同的操作public class SecondActivity extends Activity { @BindView(R.id.secoond_btn) Button secoondBtn; @Inject Gson gson; @Inject Gson gson1; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_second); ButterKnife.bind(this); MyApplication.get(this).getComponent().inject(this); } @OnClick(R.id.secoond_btn) public void onViewClicked() { Log.e("SecondActivity", "gson:" + gson.hashCode()+" gson1"+gson1.hashCode()); }}
我的测试结果如下:
E/MainActivity: gson:1111566360 gson11111566360
E/SecondActivity: gson:1111566360 gson11111566360
可以看到四个HashCode都一样,我们的全局单例模式算是实现了。
还有两个注解的使用,@dependencies和subComponent有空再说吧,是用来描述component的组织关系的。
- dagger2的配置及基本使用(一)
- dagger2的基本使用一
- Dagger2的基本配置
- Dagger2的基本使用
- dagger2 的基本使用
- Dagger2使用(一)Dagger2 介绍
- Dagger2 的简单使用 (一)
- hadoop的基本简介及安装、配置、使用(一)
- hive的基本简介及安装、配置、使用(一)
- Hbase的基本简介及安装、配置、使用(一)
- Dagger2.0基本使用及简单原理
- Kotlin 踩坑日记(一)Kotlin Dagger2 配置使用
- TDDL+DIAMOND的配置及使用(一):基本介绍
- Dagger2教程一之配置(原)
- (一)Dagger2+retrofit2.0 的初次使用
- Dagger2的组件依赖及使用详解
- 【zZ】dagger2使用心得(一)
- 解锁Dagger2使用姿势(一)
- Android项目针对libs(armeabi,armeabi-v7a,x86)进行平台兼容
- (十)linux下用标准i/o实现格式化输出并且把时间每隔一秒输出到文件中
- 《win10专业版永久激活》
- Java序列化和反序列化的简单理解
- iis 6 7 8预加载,提升web访速
- dagger2的配置及基本使用(一)
- Bootstrap基础10——徽章badge
- Java Instrumentation类相关文章合集
- 利用伪类清除浮动
- Rhel Linux7.2 安装Apache服务
- java.lang.VerifyError
- 【华为机试】字符串排序
- 响应式布局值之Bootstrap
- C++_多态&多态的对象模型