依赖注入
指程序运行过程中,调用者需要被调用者的辅助,但是创建被调用者对象的工作不再由调用者来完成(因此称为控制反转(IOC:Inversion of Control)),而是由相关的容器控制程序将被调用者的对象在外部创建出来并注入到调用者的引用中.(以HRSystem 和person为例)
public class HRSystem {
@Inject
Person person;
public staticvoid main(String[] args) {
}
}
为什么要使用依赖注入
依赖注入是实现控制反转的方式之一(另一方式是依赖查找),目的就是为了让调用者和被调用者之间解耦
可以注入依赖的模拟实现,使得测试变得更加简单.
(一)ButterKnife
https://github.com/JakeWharton/butterknife
用途:主要用来简化各种初始化控件的操作
配置:(高版本需要添加仓库)
- 在build.gradle文件中dependencies节点添加如下代码 Add this to you project-level build.gradle:
buildscript{
repositories {
mavenCentral()
}
dependencies {
classpath'com.neenbedankt.gradle.plugins:android-apt:1.8'
}
}
Add this to your module-levelbuild.gradle:
apply plugin: 'android-apt'
android {
...
}
dependencies {
compile'com.jakewharton:butterknife:8.1.0'
apt'com.jakewharton:butterknife-compiler:8.1.0'
}
- 在Android Studio中点击 File-->Settings-->Plugins-->Browse repositories,搜索Android ButterKnife Zelezny插件,安装成功以后重启Android Studio.
- 在布局文件中添加控件的时候,所有需要在Activity/Fragment代码中进行控制的控件都要添加id属性
- 在Activity/Fragment代码中,将鼠标放在布局文件的引用上(即R.layout.activitymain中的activitymain上面),此时按快捷键Alt + Insert或鼠标右键选择Generate
- 在弹出的菜单中选择Generate ButterKnife Injections,此时会再次弹出一个对话框
- 新的对话框中点击confirm后直接生成控件的引用,代替findViewById
- 如果需要处理控件的点击事件,可以选择对应控件的OnClick复选框.
- 如果是ListView的Item视图,还可以选择左下角的Create ViewHolder复选框,生成ViewHolder静态类.
使用技巧:
在AndroidStudio\plugins\android\lib\templates\gradle-projects\NewAndroidModule\recipe.xml.ftl中添加如下代码,以后新创建的工程默认会添加Butterknife依赖:
<dependencymavenUrl="com.jakewharton:butterknife:7.0.1" />
(二)AndroidAnnotations
主页: http://androidannotations.org/
用途:1.使用依赖注入Views,extras,System Service,resources
2.简化线程模型
3.事件绑定
4.REST Client
配置:
1.在project/build.gradle文件中按下图所示添加代码:
mavenCentral()
classpath'com.neenbedankt.gradle.plugins:android-apt:1.8'
mavenCentral()
mavenLocal()
2.在app/build.gradle文件中按下图所示添加代码:
apply plugin: 'android-apt'
apt {
arguments {
androidManifestFilevariant.outputs[0]?.processResources?.manifestFile
}
}
apt"org.androidannotations:androidannotations:4.0.0"
compile"org.androidannotations:androidannotations-api:4.0.0"
注意事项:
*Manifest中注册的activity要在原类名后追加下划线”_”
* 使用注解的控件和方法不能使用private修饰符
* 大型项目并不适用
(三)Dagger2
主页: https://github.com/google/dagger
配置:
1.在project/build.gradle文件中按下图所示添加代码:classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'
2.在app/build.gradle文件中按下图所示添加代码:
* apply plugin: 'com.neenbedankt.android-apt'
* compile 'com.google.dagger:dagger:2.2'
* apt 'com.google.dagger:dagger-compiler:2.2'
* provided 'org.glassfish:javax.annotation:10.0-b28'
主要的注解:
- @Provides:用来修饰方法,方法的返回类型就是所提供的依赖类型,可以简单的把方法的返回值理解为我们通常要new出来的对象.
@Provides方法都会用provide作为前缀
- @Module:所有的@Provides方法都必须放到一个Moudle中,一个Moudle就是使用@Moudle修饰的类,可以简单的理解为一个持有各种对象的仓库.用来给@Component组件提供实例化的对象.
Android中有三种Module:ApplicationModule,ActivityModule,UserModule,分别提供整个应用级别的(只生成一个该组件的实例),Activity级别的,用户级别的Module。
@Module类都用Module作为后缀
- @Inject:通常在需要依赖的地方使用这个注解,简单的理解为声明一个对象
- @Component它是@Inject和@Module的桥梁,它的主要作用就是连接这两个部分.
我们必须用@Component注解一个接口,为该注解传入Module类,或者添加其依赖的组件
@Component注解的接口或抽象类以Component为后缀
- @Component的实现类
@Component注解的接口或抽象类,Dagger将会为该接口或者抽象类生成一个实现,这个实现的命名是在接口或抽象类前面加上Dagger,如MyComponent生成的实现是DaggerMyComponent
使用步骤:
1.创建Module,并在其中创建Provides.示例代码:
@Module
public class MainActivityModuel {
@Provides
User provideUser(){
return new User("zhangsan",12,"18612345678");
}
}
2.创建Component.示例代码:
@Component(modules = MainActivityModuel.class)
public interface MainActivityComponent {
void inject(MainActivityactivity);
}
3.Rebuild工程,生成对应的以Dagger开始的工具类
4.利用对应的以Dagger工具类初始化,并注入对象.示例代码:
public class MainActivity extends AppCompatActivity {
@Inject
Useruser;
@Override
protected void onCreate(BundlesavedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
MainActivityComponent component =DaggerMainActivityComponent.builder().mainActivityModuel(newMainActivityModuel()).build();
component.inject(this);
}
}