依赖注入,ORM及相关框架

来源:互联网 发布:淘宝店女装运动服 编辑:程序博客网 时间:2024/05/20 18:20
  • 基本概念
控制反转(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 nameString 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
原创粉丝点击