依赖注入,ORM及相关框架

 
 
  • 基本概念
控制反转(Inversion of Control,英文缩写为 IoC):创建被调用者的工作不再由调用者来完成,因此称为控制反转。
依赖注入(Dependency Injection,简称DI):控制反转的主要实现方式,可以通过反射方式实现(ViewUtils,反射注入),也可以非反射方式(Dagger2)
ORM:即Object-Relational Mapping(对象关系映射),它的作用是在关系型数据库和业务实体对象之间作一个映射,这样,我们在具体的操作业务对象的时候,就不需要再去和复杂的SQL语句打交道,只需简单的操作对象的属性和方法。(ORMLite,DBUtils,greendao)
 
 
  • Dagger2:

1.介绍:
依赖注入就是将调用者需要的另一个对象实例不在调用者内部实现,而是通过一定的方式从外部传入实例,解决了各个类之间的耦合。

那么这个外部,到底指的是哪里,如果指的是另一个类,那么,另一个类内部不就耦合了。能不能有一种方式,将这些构造的对象放到一个容器中,具体需要哪个实例时,就从这个容器中取就行了。那么,类的实例和使用就不在有联系了,而是通过一个容器将他们联系起来。实现了解耦。这个容器,便是Dagger2

Dagger2是Google出的依赖注入框架。肯定有小伙伴疑问,为什么会有个 2 呢。该框架是基于square开发的dagger基础上开发的。

Dagger2的原理是在编译期生成相应的依赖注入代码。这也是和其他依赖注入框架不同的地方,其他框架是在运行时期反射获取注解内容,影响了运行效率。

2.导入Dagger2:

在工程的build.gradle文件中添加android-apt插件:

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:

apply plugin'com.android.application'

// 应用插件
apply plugin: 'com.neenbedankt.android-apt'


android {
compileSdkVersion 
23
buildToolsVersion "24.0.1"

defaultConfig {
applicationId "com.qf.zhouyi.daggertest"
minSdkVersion 15
targetSdkVersion 23
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}

lintOptions {
warning 'InvalidPackage'
}

}

dependencies {
compile fileTree(
dir'libs'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'
}

android-aptGradle编译器的插件,根据其官方文档,主要两个目的:

  • 编译时使用该工具,最终打包时不会将该插件打入到apk中。

  • 能够根据设置的源路径,在编译时期生成相应代码。

    dagger是主要的工具类库。dagger-compiler为编译时期生成代码等相关的类库。

    android-apt的文档中,也推荐使用这种方式。因为,编译时期生成代码的类库在运行期并不需要,那么将其分为两个库,(运行类库dagger)和(编译器生成代码类库(dagger-compiler)),那么在打包时,就不需要将dagger-compiler打入其中(用不到),减小APK 的大小。

3.使用

Dagger2将程序分为三个部分。 
- 实例化部分:对象的实例化。类似于容器,将类的实例放在容器里。 
- 调用者:需要实例化对象的类。 
- 沟通桥梁:利用Dagger2中的一些API 将两者联系。

实例化部分:Module

package com.qf.zhouyi.daggerdemo;

import android.util.Log;

public class Person {


public void doSomething(){
Log.e("qf", "do something");
}
}
package com.qf.zhouyi.daggerdemo;

import dagger.Module;
import dagger.Provides;

/**
* Created by zhouyi on 16/8/22.
*/
@Module
public class PersonModule {
@Provides
Person providePerson(){
return new Person();
}
}

沟通部分Component

package com.qf.zhouyi.daggerdemo;

import dagger.Component;

/**
* Created by zhouyi on 16/8/22.
*/
@Component(modules = {PersonModule.class})
public interface PersonComponent {
void inject(MainActivity mainActivity);
}

一个Component可以沟通多个module:

package com.qf.zhouyi.daggerdemo;

import dagger.Component;

/**
* Created by zhouyi on 16/8/22.
*/
@Component(modules = {PersonModule.class,GsonModule.class})
public interface PersonComponent {
void inject(MainActivity mainActivity);
}
package com.qf.zhouyi.daggerdemo;

import com.google.gson.Gson;

import dagger.Module;
import dagger.Provides;

/**
* Created by zhouyi on 16/8/22.
*/
@Module
public class GsonModule {

@Provides
Gson provideGosn(){
return new Gson();
}
}
package com.qf.zhouyi.daggerdemo;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;

import com.google.gson.Gson;

import javax.inject.Inject;


public class MainActivity extends AppCompatActivity {

@Inject
Person person;

@Inject
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\",\n" +
" P_LANGUAGE:\"Java\",\n" +
" LOCATION:\"Malta\"\n" +
"}\n";

MyData myData = gson.fromJson(strJson,MyData.class);
Log.d("qf",myData.toString());
}
}


@Singleton 单例注解

假如,对于同一个对象,我们需要注入两次,如下方式:

package com.qf.zhouyi.daggerdemo;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;

import com.google.gson.Gson;

import javax.inject.Inject;


public class MainActivity extends AppCompatActivity {

@Inject
Person person;

@Inject
Person person2;

@Inject
Gson gson;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

DaggerPersonComponent.builder().build().inject(this);
//person.doSomething();

Log.i("dagger","person = "+ person.toString()+"; person2 = "+ person2.toString());

}
}

打印出来的对象地址是不一样的

如果要使用单例,需要在module和component里加入singleton注解

@Component(modules = {PersonModule.class})
@Singleton
public interface PersonComponent {
void inject(MainActivity mainActivity);
}
package com.qf.zhouyi.daggerdemo;

import javax.inject.Singleton;

import dagger.Module;
import dagger.Provides;

/**
* Created by zhouyi on 16/8/22.
*/
@Module
public class PersonModule {
@Provides
@Singleton
Person providePerson(){
return new Person();
}
}

但是,如果是不同的component,就无法保持单例:

package com.qf.zhouyi.daggerdemo;

import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;

import javax.inject.Inject;


public class MainActivity extends AppCompatActivity {

@Inject
Person person;

@Inject
Person person2;



@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

DaggerPersonComponent.builder().build().inject(this);
//person.doSomething();

Log.i("dagger","person = "+ person.toString()+"; person2 = "+ person2.toString());



}

public void onShow(View view) {
Intent intent = new Intent();
intent.setClass(this,MainActivity2.class);
startActivity(intent);
}
}
package com.qf.zhouyi.daggerdemo;

import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;

import javax.inject.Inject;

/**
* Created by zhouyi on 16/8/22.
*/
public class MainActivity2 extends AppCompatActivity {
@Inject
Person person3;

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);

DaggerPersonComponent.builder().build().inject(this);
//person.doSomething();

Log.i("dagger","person3 = "+ person3.toString());

}
}
package com.qf.zhouyi.daggerdemo;

import javax.inject.Singleton;

import dagger.Component;

/**
* Created by zhouyi on 16/8/22.
*/
@Component(modules = {PersonModule.class})
@Singleton
public interface PersonComponent {
void inject(MainActivity mainActivity);
void inject(MainActivity2 mainActivity2);
}

思考:如何得到全局的单例



带参数实例化

package com.qf.zhouyi.daggerdemo;

import android.util.Log;

public class Person {

int aa;

public Person(int a){
aa = a;
}


public void doSomething(){
Log.e("qf", "do something " + aa);
}
}
package com.qf.zhouyi.daggerdemo;

import javax.inject.Singleton;

import dagger.Module;
import dagger.Provides;

/**
* Created by zhouyi on 16/8/22.
*/
@Module
public class PersonModule {
int aa;

PersonModule(int a){
aa = a;
}

@Provides
@Singleton
Person providePerson(){
return new Person(aa);
}

}

调用:


DaggerPersonComponent
.builder()
.personModule(new PersonModule(4))
.build()
.inject(this);
person.doSomething();

一个创建依赖另一个创建:

package com.qf.zhouyi.daggerdemo;

import dagger.Module;
import dagger.Provides;

/**
* Created by zhouyi on 16/8/22.
*/
@Module
public class IntModule {
@Provides
int providesInt(){
return 5;
}
}
package com.qf.zhouyi.daggerdemo;

import dagger.Component;

/**
* Created by zhouyi on 16/8/22.
*/
@Component(modules = IntModule.class)
public interface IntComponent {
int provideInt();
}
package com.qf.zhouyi.daggerdemo;

import javax.inject.Singleton;

import dagger.Module;
import dagger.Provides;

/**
* Created by zhouyi on 16/8/22.
*/
@Module
public class PersonModule {
// int aa;
//
// PersonModule(int a){
// aa = a;
// }

@Provides
@Singleton
Person providePerson(int a){
return new Person(a);
}

}
package com.qf.zhouyi.daggerdemo;

import javax.inject.Singleton;

import dagger.Component;

/**
* Created by zhouyi on 16/8/22.
*/
@Component(modules = {PersonModule.class},dependencies = IntComponent.class)
@Singleton
public interface PersonComponent {
void inject(MainActivity mainActivity);
void inject(MainActivity2 mainActivity2);
}

调用:

IntComponent intComponent = DaggerIntComponent.builder().build();

DaggerPersonComponent.builder()
.intComponent(intComponent)
.personModule(new PersonModule())
.build().inject(this);
person.doSomething();


多个不同的构造方法:

package com.qf.zhouyi.daggerdemo;

import android.util.Log;

public class Person {

int aa;
String mstrMsg;

public Person(int a){
aa = a;
}

public Person(String strMsg){
mstrMsg = strMsg;
}

public void doSomething2(){
Log.e("qf","do something2"+mstrMsg);
}


public void doSomething(){
Log.e("qf", "do something " + aa);
}
}

在上例的基础上,增加stringmodule,stringcomponent:

package com.qf.zhouyi.daggerdemo;

import dagger.Component;

/**
* Created by zhouyi on 16/8/22.
*/
@Component(modules = StringModule.class)
public interface StringComponent {
String provideString();
}
package com.qf.zhouyi.daggerdemo;

import dagger.Module;
import dagger.Provides;

/**
* Created by zhouyi on 16/8/22.
*/
@Module
public class StringModule {
@Provides
String providesString(){
return "abc";
}
}

personcomponet:

package com.qf.zhouyi.daggerdemo;

import javax.inject.Singleton;

import dagger.Component;

/**
* Created by zhouyi on 16/8/22.
*/
@Component(modules = {PersonModule.class},dependencies = {IntComponent.class,StringComponent.class})
@Singleton
public interface PersonComponent {
void inject(MainActivity mainActivity);
//void inject(MainActivity2 mainActivity2);
}

personmodule:

package com.qf.zhouyi.daggerdemo;

import javax.inject.Named;

import dagger.Module;
import dagger.Provides;

/**
* Created by zhouyi on 16/8/22.
*/
@Module
public class PersonModule {
// int aa;
// String mstrMsg;
//
// PersonModule(int a){
// aa = a;
// }
//
// PersonModule(String strMsg){
// mstrMsg = strMsg;
// }


@Named("int")
@Provides
Person providePerson(int a){
return new Person(a);
}

@Named("string")
@Provides
Person providePerson2(String strMsg){
return new Person(strMsg);
}

}

调用:

IntComponent intComponent = DaggerIntComponent.builder().build();
StringComponent stringComponent = DaggerStringComponent.builder().build();

DaggerPersonComponent.builder()
.intComponent(intComponent)
.stringComponent(stringComponent)
.personModule(new PersonModule())
.build().inject(this);
person.doSomething();
person2.doSomething2();

可以使用两个自定义注解替换前面的name注解:

@Qualifier
@Retention(RetentionPolicy.RUNTIME)
public @interface PersonInt {
}
@Qualifier
@Retention(RetentionPolicy.RUNTIME)
public @interface PersonString {
}

懒加载Lazy和强制重新加载Provider

@PersonInt
@Inject
Lazy<Person> person;

Person p = person.get();
Log.i("dagger","person = "+ p.toString());
Person p2 = person.get();
Log.i("dagger","person2 = "+ p2.toString());

上面打印出来地址一样

改成:

@PersonInt
@Inject
Provider<Person> person;

打印地址不一样


package  com.qf.zhouyi.ormlitetest ;

import  android.os.Bundle ;
import  android.support.v7.app.AppCompatActivity ;
import  android.util.Log ;

import  java.util.List ;

public class  MainActivity  extends  AppCompatActivity {

     @Override
     protected void  onCreate (Bundle savedInstanceState) {
         super .onCreate(savedInstanceState) ;
         setContentView(R.layout. activity_main ) ;

         testAddUser() ;
     }

     public void  testList ()
    {
        DatabaseHelper helper = DatabaseHelper. getHelper ( this ) ;
        try
         {
            User u1 =  new  User( "zhy-android" "2B青年" ) ;
             u1.setId( 2 ) ;
             List<User> users = helper.getUserDao().queryForAll() ;
             Log. e ( "TAG" users.toString()) ;
         catch  (Exception e)
        {
            e.printStackTrace() ;
         }
    }

     public void  testAddUser ()
    {

        User u1 =  new  User( "zhy" "2B青年" ) ;
         DatabaseHelper helper = DatabaseHelper. getHelper ( this ) ;
        try
         {
            helper.getUserDao().create(u1) ;
             u1 =  new  User( "zhy2" "2B青年" ) ;
             helper.getUserDao().create(u1) ;
             u1 =  new  User( "zhy3" "2B青年" ) ;
             helper.getUserDao().create(u1) ;
             u1 =  new  User( "zhy4" "2B青年" ) ;
             helper.getUserDao().create(u1) ;
             u1 =  new  User( "zhy5" "2B青年" ) ;
             helper.getUserDao().create(u1) ;
             u1 =  new  User( "zhy6" "2B青年" ) ;
             helper.getUserDao().create(u1) ;

             testList() ;

         catch  (Exception e)
        {
            e.printStackTrace() ;
         }
    }
}

package  com.qf.zhouyi.ormlitetest ;
 
import  com.j256.ormlite.field.DatabaseField ;
import  com.j256.ormlite.table.DatabaseTable ;
 
@DatabaseTable ( tableName  "tb_user" )
public class  User
{
    @DatabaseField ( generatedId  true )
    private int  id ;
    @DatabaseField ( columnName  "name" )
    private  String  name ;
    @DatabaseField ( columnName  "desc" )
    private  String  desc ;
 
   public  User()
   {
   }
 
    public  User(String name String desc)
   {
       this . name  = name ;
      this . desc  = desc ;
    }
 
    public int  getId ()
   {
       return  id ;
    }
 
    public void  setId ( int  id)
   {
       this . id  = id ;
    }
 
    public  String  getName ()
   {
       return  name ;
    }
 
    public void  setName (String name)
   {
       this . name  = name ;
    }
 
    public  String  getDesc ()
   {
       return  desc ;
    }
 
    public void  setDesc (String desc)
   {
       this . desc  = desc ;
    }

    @Override
    public  String  toString () {
       return  "User{"  +
             "id="  id  +
             ", name='"  name  ' \' +
             ", desc='"  desc  ' \' +
             '}' ;
    }
}







  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值