- 基本概念
控制反转(Inversion of Control,英文缩写为IoC):创建被调用者的工作不再由调用者来完成,因此称为控制反转。
依赖注入(Dependency Injection,简称DI):控制反转的主要实现方式,可以通过反射方式实现(ViewUtils,反射注入),也可以非反射方式(Dagger2)
ORM:即Object-Relational Mapping(对象关系映射),它的作用是在关系型数据库和业务实体对象之间作一个映射,这样,我们在具体的操作业务对象的时候,就不需要再去和复杂的sql语句打交道,只需简单的操作对象的属性和方法。(Ormlite,dbutils,greendao)
- Dagger2:
1.介绍:
依赖注入就是将调用者需要的另一个对象实例不在调用者内部实现,而是通过一定的方式从外部传入实例,解决了各个类之间的耦合。
那么这个外部,到底指的是哪里,如果指的是另一个类,那么,另一个类内部不就耦合了。能不能有一种方式,将这些构造的对象放到一个容器中,具体需要哪个实例时,就从这个容器中取就行了。那么,类的实例和使用就不在有联系了,而是通过一个容器将他们联系起来。实现了解耦。这个容器,便是。
是Google出的依赖注入框架。肯定有小伙伴疑问,为什么会有个 2 呢。该框架是基于开发的基础上开发的。
的原理是在编译期生成相应的依赖注入代码。这也是和其他依赖注入框架不同的地方,其他框架是在运行时期反射获取注解内容,影响了运行效率。
2.导入Dagger2:
dependencies {
classpath'com.android.tools.build:gradle:2.1.2'
// 添加android-apt 插件
classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
app的build.gradle:
applyplugin:'com.android.application'
// 应用插件
apply plugin: 'com.neenbedankt.android-apt'
android {
compileSdkVersion23
buildToolsversion"24.0.1"
defaultConfig {
applicationId"com.qf.zhouyi.daggertest"
minSdkVersion15
targetSdkVersionversionCode1
versionName"1.0"
}
buildTypes {
release {
minifyEnabledfalse
proguardFilesgetDefaultProguardFile('proguard-android.txt'),'proguard-rules.pro'
}
}
lintOptions {
warning 'InvalidPackage'
}
}
dependencies {
compile filetree(dir:'libs',89); background-color:inherit">include: ['*.jar'])
testCompile'junit:junit:4.12'
compile'com.android.support:appcompat-v7:23.4.0'
// dagger 2 的配置
compile 'com.google.dagger:dagger:2.4'
apt 'com.google.dagger:dagger-compiler:2.4'
compile 'org.glassfish:javax.annotation:10.0-b28'
// 添加java 注解库
compile'com.google.code.gson:gson:2.7'
}是编译器的插件,根据其官方文档,主要两个目的:
编译时使用该工具,最终打包时不会将该插件打入到apk中。
在的文档中,也推荐使用这种方式。因为,编译时期生成代码的类库在运行期并不需要,那么将其分为两个库,(运行类库)和(编译器生成代码类库()),那么在打包时,就不需要将打入其中(用不到),减小APK 的大小。
3.使用
将程序分为三个部分。
- 实例化部分:对象的实例化。类似于容器,将类的实例放在容器里。
- 调用者:需要实例化对象的类。
- 沟通桥梁:利用中的一些API 将两者联系。
实例化部分:Module
package com.qf.zhouyi.daggerdemo;
import android.util.Logpublic class Person {
public void doSomething(){
Log.e("qf",89); background-color:inherit">"do something") }
}
packagecom.qf.zhouyi.daggerdemoimportdagger.Moduledagger.Provides
/**
* Created by zhouyi on 16/8/22.
*/
@Module
public classPersonModule {
@Provides
PersonprovidePerson(){
return newPerson()}
}
沟通部分
dagger.Component@Component(modules= {PersonModule.class})
public interfacePersonComponent {
voidinject(MainActivity mainActivity);
}
一个Component可以沟通多个module:
import * Created by zhouyi on 16/8/22.
*/
modules = {PersonModule.class,GsonModule.public interface PersonComponent {
void ;
}
import com.google.gson.Gsonpublic class GsonModule {
Gson provideGosn(){
return new Gson() }
}
import android.os.Bundleimport android.support.v7.app.AppCompatActivityjavax.inject.Injectpublic class MainActivity extends AppCompatActivity {
@Inject
Person person Gson gson@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) DaggerPersonComponent.builder().build().inject(this) person.doSomething() String strjson = "{\n" +
" NAME:\"Albert Attard," P_LANGUAGE:Java" LOCATION:Malta\"\n"}" MyData myData = gson.fromJson(strjsonclass) Log.d( }
}
@Singleton 单例注解
假如,对于同一个对象,我们需要注入两次,如下方式:
person2 //person.doSomething();
Log.i("dagger""person = "+ person.toString()+"; person2 = "+ person2.toString());
}
}
打印出来的对象地址是不一样的
如果要使用单例,需要在module和component里加入singleton注解
class})
@Singleton
;
}
javax.inject.Singletonpublic class PersonModule {
@Singleton
Person providePerson(){
return new Person()但是,如果是不同的component,就无法保持单例:importandroid.content.Intentimport android.view.View
}
onShow(View view) {
Intent intent = new Intent() intent.setClass(this,MainActivity2. startActivity(intent)android.support.annotation.Nullable */
public class MainActivity2 extends AppCompatActivity {
person3onCreate(@Nullable Bundle savedInstanceState) {
activity_main2)"person3 = "+ person3.toString()) void inject(MainActivity2 mainActivity2);
}
思考:如何得到全局的单例
带参数实例化
public class Person {
int aa public Person(int a){
aa = a }
"do something " + aa) }
}
public class PersonModule {
PersonModule( }
return new Person( }
}
调用:
DaggerPersonComponent
.builder()
.personModule(new PersonModule(4))
.build()
.inject(;
;
public class IntModule {
int providesInt(){
return 5modules = IntModule.class)
public interface IntComponent {
provideInt()public class PersonModule {
// int aa;
//
// PersonModule(int a){
// aa = a;
// }
providePerson(int a){
return new Person(a) }
}
class}dependencies = IntComponent.class)
inject(MainActivity mainActivity)IntComponent intComponent = DaggerIntComponent.builder().build()
DaggerPersonComponent.builder()
.intComponent(intComponent)
.personModule(new PersonModule())
.build().inject(多个不同的构造方法:
String mstrMsg }
public Person(String strMsg){
mstrMsg = strMsgdoSomething2(){
Log.e("do something2"+mstrMsg) }
}在上例的基础上,增加stringmodule,stringcomponent:
modules= StringModule.public interface StringComponent {
String provideString()public class StringModule {
String providesstring(){
return "abc"personcomponet:dependencies= {IntComponent.PersonComponent {
//void inject(MainActivity2 mainActivity2);
}
personmodule:
javax.inject.Named// String mstrMsg;
// PersonModule(String strMsg){
// mstrMsg = strMsg;
@Named("int")
int a){
return new Person(a)"string")
providePerson2(String strMsg){
return new Person(strMsg);
StringComponent stringComponent = DaggerStringComponent.builder().build()
DaggerPersonComponent.builder()
.intComponent(intComponent)
.stringComponent(stringComponent)
.personModule(person2.doSomething2()可以使用两个自定义注解替换前面的name注解:@Qualifier@Retention(RetentionPolicy.RUNTIME)
public @interface PersonInt {
}
PersonString {
}
懒加载Lazy和强制重新加载Provider
@PersonInt
@Inject
Lazy<Person> ;
Person p = person.get();
Log.i("person = "+ p.toString());
Person p2 = "person2 = "+ p2.toString());
上面打印出来地址一样
改成:
@Inject
Provider<Person> 打印地址不一样
import android.os.Bundle ;android.support.v7.app.AppCompatActivity android.util.Log java.util.List publicclass MainActivity extends AppCompatActivity{
@Overrideprotectedvoid onCreate (BundlesavedInstanceState){super .onCreate(savedInstanceState) setContentView(R.layout. activity_main ) testAddUser() }
publicvoid testList (){DatabaseHelperhelper=DatabaseHelper. getHelper ( this tryUseru1= new User( "zhy-android" , "2B青年" u1.setId( 2 List<User>users=helper.getUserDao().queryForAll() Log. e ( "TAG" users.toString()) } catch (Exceptione)e.printstacktrace() }testAddUser {
"zhy" helper.getUserDao().create(u1) u1= "zhy2" "zhy3" "zhy4" "zhy5" "zhy6" testList() }
@DatabaseTable ( tableName = "tb_user" )User@DatabaseField generatedId = true )privateint id columnName "name" private String name "desc" desc public User()User(Stringname Stringdesc). name =name desc =desc publicint getId return setId int id)id =id String getName setName (Stringname)getDesc setDesc (Stringdesc)toString (){return "User{" +"id=" + ",name='" + ' \' ' '}' }Dagger2Dagger2squaredaggerDagger2build.gradleandroid-aptandroid-aptGradledaggerdagger-compilerandroid-aptdaggerdagger-compilerdagger-compilerDagger2Dagger2Component