Square公司旗下两把匕首:左手一把ButterKnife,右手一把Dragger2
本文只是介绍如何让你去用Dragger2,具体介绍不多赘述。
作为理工男,让我看字还不如给我一打代码实在,边敲边熟悉这个框架,再去看那些文字描述,会事半功倍。
依赖
class Phone{
private Battery battery;
}
class Battery{
}
手机类(Phone)持有对电池(Battery)的引用,故称Phone类对Battery类有一个依赖。
注入
注入分三种:构造注入、接口注入、注解注入
构造注入
class Phone{
private Battery battery;
//通过构造方法中将battery注入
public Phone(Battery battery){
this.battery = battery;
}
}
接口注入
public interface Injection<T>{
void inject(T t);
}
class Phone implements Injection<Battery>{
private Battery battery;
//通过实例化的接口方法注入依赖
void inject(Battery battery){
this.battery = battery;
}
}
注解注入
class Phone{
//注解
@Inject
private Battery battery;
}
以上是简介注解的图解
环境配置
Project Gradle
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:2.2.2'
//添加的代码段
classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'
}
}
allprojects {
repositories {
jcenter()
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
Module Gradle
apply plugin: 'com.android.application'
//注意添加这个plugin
apply plugin: 'android-apt'
android {
compileSdkVersion 25
buildToolsVersion "25.0.2"
defaultConfig {
applicationId "com.sinla.dragger2"
minSdkVersion 19
targetSdkVersion 25
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:25.3.0'
// 添加的代码段
compile 'com.google.dagger:dagger:2.0.2'
apt 'com.google.dagger:dagger-compiler:2.0.2'
provided 'org.glassfish:javax.annotation:10.0-b28'
}
接下来开始
sample1
class Phone{
@Inject
private Battery battery;
//注:需要在Build Project之后才会出现DaggerAppComponent
public Phone(){
DaggerAppComponent.builder()
.build()
.inject(this);
}
}
class Battery{
@Inject
public Battery(){};
}
@Component
interface AppComponent{
void inject(Phone phone);
}
sample2
如果是构造函数有参数的怎么办?
这时候得引入@Module
class Phone{
@Inject
private Battery battery;
//注:需要在Build Project之后才会出现DaggerAppComponent
public Phone(){
DaggerAppComponent.builder()
//根据@Component(modules = AppModule.class)
//build之后自动生成
.appModule(new AppModule())
.build()
.inject(this);
battery.say();
}
}
class Battery{
private static final String TAG = "Battery";
private String name;
@Inject
public Battery(String name){
this.name = name;
};
public void say(){
Log.e(TAG, "say: " + name);
}
}
//注意这边的改变
@Component(modules = AppModule.class)
interface AppComponent{
void inject(Phone phone);
}
//从@provides方法提供的类型来搜索
@Module
public class AppModule {
//方法名非必需以provider开头
@Provides
public String providerString(){
return "Jack";
}
//以下和sample2无关
//如果provider方法有参数的话
//会自动从module里面寻找是否有返回该参数类型的provider
//即该Provider会从 providerString中返回String作为参数
@Provider
public Object providerObject(String name){
return new Object();
}
}
sample3
基本常用的都差不多了,现在讨论如果Module里面有两个相同返回参数的该怎么办?
这时候得引入@Qualifier
/**
* 如果Module 中有两个相同的 返回参数,即用来作为区分
*/
@Qualifier
@Retention(RetentionPolicy.RUNTIME)
public @interface QualifierA {
}
@Qualifier
@Retention(RetentionPolicy.RUNTIME)
public @interface QualifierB {
}
class Phone{
@QualifierA
@Inject
private Battery battery1;
@QualifierB
@Inject
private Battery battery2;
public Phone(){
DaggerAppComponent.builder()
.appModule(new AppModule())
.build()
.inject(this);
battery1.say();
battery2.say();
}
}
class Battery{
private static final String TAG = "Battery";
private String name;
@Inject
public Battery(String name){
this.name = name;
};
public void say(){
Log.e(TAG, "say: " + name);
}
}
@Component(modules = AppModule.class)
interface AppComponent{
void inject(Phone phone);
}
@Module
public class AppModule {
@QualifierA
@Provides
public String providerStringJack(){
return "Jack";
}
@QualifierB
@Provides
public String providerStringWilliam(){
return "William";
}
}
输出:
say:jack
say:william
sample4
接下来可以继续讨论如果构造函数传入的参数对象,能否变成单例化?
这时候得引入@Scope
/**
* 局部单例化,仅创建一次
* 类似于 @Singleton
*/
@Scope
@Retention(RetentionPolicy.RUNTIME)
public @interface AppScope {
}
class Phone{
@Inject
private Battery battery1, battery2;
public Phone(){
DaggerAppComponent.builder()
.appModule(new AppModule())
.build()
.inject(this);
battery1.say();
battery2.say();
}
}
class Battery{
private static final String TAG = "Battery";
private User user;
@Inject
public Battery(User user){
this.user = user;
};
public void say(){
Log.e(TAG, "say: " + user.hashCode());
}
}
//用来判断HashCode
public class User{
private static final String TAG = "User";
public User(){
Log.e(TAG, "new instance");
}
}
//注意此处加上@AppScope
@AppScope
@Component(modules = AppModule.class)
interface AppComponent{
void inject(Phone phone);
}
@Module
public class AppModule {
//注意此处加上@AppScope
@AppScope
@Provides
public User providerUser(){
return new User();
}
}
输出:
User:new instance
Battery:”say:”:@11111
Battery:”say:”:@11111
可见User只有实例一次
第一次写博客,纯手敲,有什么疏漏欢迎指出