Skip to content

xvjialing/Dagger2

Repository files navigation

ddagger2

dagger构成

构成的元素有三种:Module,Component,Container

dagger2构成

dagger2使用

注解符 作用
@Inject 通常在需要依赖的地方使用这个注解。换句话说,你用它告诉Dagger这个类或者字段需要依赖注入。这样,Dagger这回构造一个一个这个类的实例并满足他们的依赖。
@Module Module类里面的方法专门提供依赖,所以我们定义一个类,用@Module注解,这样Dagger在构造类的实例时候,就知道从哪里去寻找需要的依赖。modules的一个重要的特征是他们设计为分区并组合在一起(比如说,我们的app中可以有多个组成在一起的modules)
@Provide 在modules中,我们定义的方法是用这个注解,以此来告诉Dagger我们想要构造对象并提供这些依赖。
@Component Components从根本上说就是一个注入器,也可以说是@Inject和@Module的桥梁,它的主要作用就是连接这两部分。Components可以提供所有定义了的类型的实例,比如:我们必须用@Component注解一个接口然后列出所有的

简单示例

先定义一个云端API存储服务ApiService和一个本地存储服务UserStore。

ApiService.class

public class ApiService {

    private static final String TAG=ApiService.class.getSimpleName();

    public void register(){
        Log.d(TAG, "register: ApiService");
    }
}

UserStore.class

public class UserStore {

    private static final String TAG=ApiService.class.getSimpleName();

    public void register(){
        Log.d(TAG, "register: UserSore");
    }
}

再定义一个用户操作管理类UserManager.class

public class UserManager {

    private UserStore userStore;

    private ApiService apiService;

    public UserManager() {
        userStore=new UserStore();

        apiService=new ApiService();
    }

    public void register(){

        userStore.register();

        apiService.register();
    }
}

最后创建一个MainActivity

public class MainActivity extends AppCompatActivity {

    private UserManager userManager;

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

        userManager = new UserManager();

        userManager.register();

    }
}

这样一个简单的服务就完成了。下面用Dagger的方法实现一个简单的依赖注入。

首先创建一个Module类UserModule

import dagger.Module;
import dagger.Provides;

@Module    //以此显示这是一个Module
public class UserModule {

    @Provides  //告诉Dagger想要构造的对象并提供这个依赖
    public ApiService getApiService(){
        return new ApiService();
    }
}

然后创建一个Component接口UserComponent

@Component(modules = {UserModule.class})   //这句话将Componet与module关联起来
public interface UserComponent {

    void inject(MainActivity activity);  //这句话将Component与Container(也就是Activity)关联起来

}

最后在MainActivity中进行注入

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

import javax.inject.Inject;

public class MainActivity extends AppCompatActivity {

    @Inject   //告诉dagger此处需要依赖注入
    ApiService mApiService;

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

        DaggerUserComponent.create().inject(this);

        mApiService.register();

    }
}

这样一个简单的依赖注入就完成了。

下面是一个带ApiService参数注入的例子。

首先改变一下UserManager,暂时只使用ApiService

public class UserManager {

    private ApiService apiService;

    public UserManager(ApiService apiService) {

        this.apiService=apiService;
    }

    public void register(){

        apiService.register();
    }
}

再修改一下UserModule

import dagger.Module;
import dagger.Provides;

@Module    //以此显示这是一个Module
public class UserModule {

    @Provides  //告诉Dagger想要构造的对象并提供这个依赖
    public ApiService getApiService(){
        return new ApiService();
    }

    @Provides
    public UserManager userManager(ApiService apiService){
        return new UserManager(apiService);
    }
}

这里的ApiService有两种注入方法,先使用在UserModule中注入的这种方法。

UserComponent不用修改,最后修改一下MainActivity

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

import javax.inject.Inject;

public class MainActivity extends AppCompatActivity {

    @Inject
    UserManager userManager;

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

        DaggerUserComponent.create().inject(this);

        userManager.register();
    }
}

这样UserManager中带参数注入的第一种方法就完成了。

第二种方法,在ApiService的构造方法中对ApiService进行注入

public class ApiService {

    private static final String TAG=ApiService.class.getSimpleName();

    @Inject
    public ApiService() {
        Log.d(TAG, "ApiService: constractor");
    }

    public void register(){
        Log.d(TAG, "register: ApiService");
    }
}

并将UserManager中将之前注入ApiService的方法注释掉

@Module    //以此显示这是一个Module
public class UserModule {

    private static  final String TAG=UserModule.class.getSimpleName();

//    @Provides  //告诉Dagger想要构造的对象并提供这个依赖
//    public ApiService getApiService(){
//        Log.d(TAG, "getApiService: ");
//        return new ApiService();
//    }

    @Provides
    public UserManager userManager(ApiService apiService){
        Log.d(TAG, "userManager: ");
        return new UserManager(apiService);
    }
}

现在将ApiService进行修改

public class ApiService {

    private static final String TAG=ApiService.class.getSimpleName();

    public ApiService() {
        Log.d(TAG, "ApiService: constractor");
    }

    @Inject
    public ApiService(String url) {
        Log.d(TAG, "ApiService url : "+url);
    }

    public void register(){
        Log.d(TAG, "register: ApiService");
    }
}

并在UserModule中加入提供url的依赖

@Module    //以此显示这是一个Module
public class UserModule {

    private static  final String TAG=UserModule.class.getSimpleName();

    @Provides
    public String url(){
        return "www.test.com";
    }

    @Provides
    public UserManager userManager(ApiService apiService){
        Log.d(TAG, "userManager: ");
        return new UserManager(apiService);
    }
}

最终的结果是

D/ApiService: ApiService url : www.test.com
D/UserModule: userManager: 
D/ApiService: register: ApiService

说明APIservice默认调用的是带有@Inject注解的构造方法

下面在UserModule中重新加入UserStore,并在UserStore的构造方法中加入Context参数

public class UserStore {

    private static final String TAG=ApiService.class.getSimpleName();

    private Context context;

    public UserStore(Context context) {
        this.context = context;
    }

    public void register(){
        Log.d(TAG, "register: UserSore");
    }
}

然后UserManager进行修改

public class UserManager {

    private UserStore userStore;

    private ApiService apiService;

    public UserManager(ApiService apiService,UserStore userStore) {
        this.userStore=userStore;

        this.apiService=apiService;
    }

    public void register(){

        userStore.register();

        apiService.register();
    }
}

UserModule也进行修改,在UserModule的构造函数中加入Context参数

import android.content.Context;
import android.util.Log;

import dagger.Module;
import dagger.Provides;

/**
 * Created by xvjialing on 2017/12/3.
 */

@Module    //以此显示这是一个Module
public class UserModule {

    private static  final String TAG=UserModule.class.getSimpleName();

    private Context context;

    public UserModule(Context context) {
        this.context = context;
    }

    @Provides
    public String url(){
        return "www.test.com";
    }

    @Provides
    public UserStore provideUserStore(){
        return new UserStore(this.context);
    }

    @Provides
    public UserManager userManager(ApiService apiService,UserStore userStore){
        Log.d(TAG, "userManager: ");
        return new UserManager(apiService,userStore);
    }
}

最后修改MainActivity

public class MainActivity extends AppCompatActivity {

    @Inject
    UserManager userManager;

	// 因为Module中需要传参,所以DaggerUserComponent无法使用create方法,而是使用builder方法,并将context参数传入其中
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        DaggerUserComponent
                .builder()
                .userModule(new UserModule(this))
                .build()
                .inject(this);

        userManager.register();
    }
}

模块化

现在在ApiService中加入OKhttp请求

public class ApiService {

    private static final String TAG=ApiService.class.getSimpleName();

    private OkHttpClient okHttpClient;

    @Inject
    public ApiService(OkHttpClient okHttpClient){
        this.okHttpClient=okHttpClient;
    }

    public void register(){
        Log.d(TAG, "register: ApiService");
        Request request=new Request.Builder()
                .get()
                .url("http://www.xvjialing.ink:32771/girls")
                .build();
        okHttpClient.newCall(request)
                .enqueue(new Callback() {
                    @Override
                    public void onFailure(Call call, IOException e) {
                        
                    }

                    @Override
                    public void onResponse(Call call, Response response) throws IOException {
                        String result = response.body().string();
                        Log.d(TAG, "onResponse: "+result);
                    }
                });
    }
}

再创建一个HttpModule专门用来存放网络相关依赖

@Module
public class HttpModule {

//    @Singleton  //通过这个注解实现OkHttpClient永远都是单例
    @Provides
    public OkHttpClient provideOkHttpClient(){
        return new OkHttpClient().newBuilder().build();
    }
}

再在UserModule中include 刚创建的HttpModule

public class ApiService {

    private static final String TAG=ApiService.class.getSimpleName();

    private OkHttpClient okHttpClient;

    @Inject
    public ApiService(OkHttpClient okHttpClient){
        this.okHttpClient=okHttpClient;
    }

    public void register(){
        Log.d(TAG, "register: ApiService");
        Request request=new Request.Builder()
                .get()
                .url("http://www.test.ink:32771/girls")
                .build();
        okHttpClient.newCall(request)
                .enqueue(new Callback() {
                    @Override
                    public void onFailure(Call call, IOException e) {

                    }

                    @Override
                    public void onResponse(Call call, Response response) throws IOException {
                        String result = response.body().string();
                        Log.d(TAG, "onResponse: "+result);
                    }
                });
    }
}

最后在MainActivity中修改注入

public class MainActivity extends AppCompatActivity {

    @Inject
    UserManager userManager;

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

        DaggerUserComponent
                .builder()
                .userModule(new UserModule(this))
                .httpModule(new HttpModule())
                .build()
                .inject(this);

        userManager.register();
    }
}

这是第一种方式的实现方法

第二种方式是在UserComponent中添加HttpModule,别忘了先去掉在UserModule中添加的include={HttpModule.class}

@Component(modules = {UserModule.class,HttpModule.class})   //这句话将Componet与module关联起来
public interface UserComponent {

    void inject(MainActivity activity);  //这句话将Component与Container(也就是Activity)关联起来

}

第三种方式是在定义一个HttpComponent


@Component(modules = {HttpModule.class})
public interface HttpComponent {
    
}

然后在UserComponent中引用

@Component(modules = {UserModule.class},dependencies = HttpComponent.class)   //这句话将Componet与module关联起来
public interface UserComponent {

    void inject(MainActivity activity);  //这句话将Component与Container(也就是Activity)关联起来

}

创建和区分不同实例

先创建一个TestService

public class TestService {

    private static final String TAG=TestService.class.getSimpleName();
    public void test(){
        Log.d(TAG, "test: ");
    }
}

在创建一个TestModule

@Module
public class TestModule {
    
    private static final String TAG=TestModule.class.getSimpleName();

    @Named("dev")   //@Named注解用来区分不同的实例
    @Provides
    public TestService getTestServiceDev(){
        Log.d(TAG, "getTestServiceDev: ");
        return new TestService();
    }

    @Named("release")
    @Provides
    public TestService getTestServiceRelease(){
        Log.d(TAG, "getTestServiceRelease: ");
        return new TestService();
    }
}

并将TestModule加入到UserComponent中

@Component(modules = {UserModule.class,HttpModule.class, TestModule.class})   //这句话将Componet与module关联起来
public interface UserComponent {

    void inject(MainActivity activity);  //这句话将Component与Container(也就是Activity)关联起来

}

最后在MainActivity中进行注入

public class MainActivity extends AppCompatActivity {

    @Named("dev")
    @Inject
    TestService testService;


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

        DaggerUserComponent.create().inject(this);

        testService.test();
    }
}

运行得到的结果是

12-04 14:05:57.002 18705-18705/com.lytech.xvjialing.dagger2 D/TestModule: getTestServiceDev: 
12-04 14:05:57.002 18705-18705/com.lytech.xvjialing.dagger2 D/TestService: test:

说明@Named("dev")起作用了

Releases

No releases published

Packages

No packages published

Languages