dagger2 注入

In this tutorial, we’ll discuss and implement Dependency Injection (DI) in our android application. For those of you who have used DI in the past (possibly in Spring), the following section can be skipped about introduction of Android Dependency Injection.

在本教程中,我们将在android应用程序中讨论并实现依赖注入 (DI)。 对于过去曾经使用过DI(可能在Spring中 )的人,可以跳过以下部分,以介绍Android Dependency Injection。

什么是Android依赖注入? (What is Android Dependency Injection?)

You don’t create objects yourself, you let someone else create them for you.

您不是自己创建对象,而是让别人为您创建对象。

Let’s analyze what the above statement means.

让我们分析以上陈述的含义。

Imagine the following scenario: We have an Activity and we wish to save some data in the SharedPreferences. Doing this without DI would lead us to instantiate, saving, retrieving data from the SharedPreferences, all within the Activity’s boilerplate code. Something that the below illustration more or less portrays to an extent.

想象以下情况:我们有一个Activity,我们希望在SharedPreferences中保存一些数据。 在没有DI的情况下执行此操作将导致我们从Activity的样板代码中实例化,保存,从SharedPreferences中检索数据。 下图或多或少地描绘了某种东西。

Without DI

没有DI

The above approach can lead to some serious issues especially when your codebase increases in size.

上面的方法可能会导致一些严重的问题,尤其是当您的代码库增大时。

You’ll have issues with unit testing, too much boilerplate code, difficulties in modifying your current codebase with so many instances to keep an eye on (shared instances, scoped instances). This is where Android Dependency Injection Pattern can give a major boost to your code.

您将遇到单元测试问题,太多样板代码,难以修改的当前代码库(有太多实例需要关注)的问题(共享实例,作用域实例)。 在这里,Android Dependency Injection Pattern可以大大增强您的代码。

As mentioned in the dependency and with the following illustration, instead of instantiating the SharedPreferences in our Activity every time, we’d let it be injected from another class.

如依赖性和下面的说明中所述,与其让每次都在Activity中实例化SharedPreferences ,我们不如从另一个类中注入它。

With DI

带DI

So our Activity is dependent on the SharedPreferences. Thus SharedPreferences acts as a dependency for our Activity. SharedPreferences gets injected into our Activity from the outside instead of getting instantiated.

因此,我们的活动取决于SharedPreferences。 因此,SharedPreferences 充当我们Activity 的依赖项 。 SharedPreferences从外部注入到我们的Activity中,而不是实例化。

为什么要使用Android依赖注入? (Why use Android Dependency Injection?)

If you’re the boss of a company, would you prefer doing all the things yourself or delegate the tasks?

如果您是公司的老板,您希望自己做所有事情还是委派任务?

Would you prefer hiring a rookie over an expert who already knows the task?

您是否愿意聘请新手,而不是已经知道任务的专家?

In an ideal situation, the answer to both of the above questions should be the latter option.

在理想情况下,以上两个问题的答案应该是后一种选择。

That’s why Dependency Injection is so critical. Instead of instantiating SharedPreferences, Databases, Network Libraries in our Activity each time, we’ll prefer to have instances of them created somewhere else and inject them in our Activity when it’s needed.

这就是依赖注入如此重要的原因。 与其每次在我们的Activity中实例化SharedPreferences,数据库和网络库,我们都希望在其他地方创建它们的实例,并在需要时将它们注入到我们的Activity中。

These dependencies are normally used in our classes using constructors that we’ll be seeing soon.

这些依赖关系通常在我们的类中使用构造函数,我们将很快看到。

什么是匕首2? (What is Dagger 2?)

Dagger library was created by developers at Square, way back in 2012. Dagger 1 was used to create instances of classes and inject dependencies via Reflections. Improving upon the first version, and collaborating with a team of developers at Google, Dagger 2 a much faster and improved version without Reflections was introduced.

Dagger库由Square的开发人员在2012年创建。Dagger1用于创建类的实例并通过Reflections注入依赖项。 Dagger 2在第一个版本的基础上进行了改进,并与Google的开发人员团队合作,引入了一个更快,更完善的版本,而没有使用Reflections。

Dagger 2 is a compile-time android dependency injection framework and uses the Java Specification Request (JSR) 330 and uses an annotation processor.

Dagger 2是一个编译时android依赖项注入框架,它使用Java Specification Request (JSR)330并使用注释处理器。

Following are the basic annotations used in Dagger 2:

以下是Dagger 2中使用的基本注释:

  1. @Module : This is used on the class that does the work of constructing objects that’ll be eventually provided as dependencies.@Module :这用于完成构造最终将作为依赖项提供的对象的类的类。
  2. @Provides : This is used on the methods inside the Module class that’ll return the object.@Provides :这用于将返回对象的Module类内部的方法上。
  3. @Inject : This is used upon a constructor, field or a method and indicates that dependency has been requested.@Inject :用于构造函数,字段或方法,表示已请求依赖项。
  4. @Component : The Module class doesn’t provide the dependency directly to the class that’s requesting it. For this, a Component interface is used that acts as a bridge between @Module and @Inject.@Component :Module类不直接向请求它的类提供依赖关系。 为此,使用了一个Component接口,它充当@Module和@Inject之间的桥梁。
  5. @Singleton : This indicates that only a single instance of the dependency object would be created.@Singleton :这表示将仅创建依赖项对象的单个实例。

Don’t worry if the above stuff went over your head. We’ll now develop an application that uses Dagger and provides SharedPreferences as the dependency in our Activity.

不用担心上面的东西是否超出您的范围。 现在,我们将开发一个使用Dagger并在活动中提供SharedPreferences作为依赖项的应用程序。

Android依赖注入示例项目 (Android Dependency Injection Example Project)

Our application would consist of a Single Activity wherein we’ll save and retrieve the data from our EditTexts into our SharedPreferences.

我们的应用程序将包含一个单一活动,在该活动中,我们将把EditTexts中的数据保存并检索到SharedPreferences中。

First and foremost, add the following dependencies in the build.gradle file.

首先,在build.gradle文件中添加以下依赖build.gradle

compile 'com.google.dagger:dagger:2.10'
annotationProcessor 'com.google.dagger:dagger-compiler:2.10'

Let’s analyze how we’ll use Dagger and the above-mentioned annotations to bring in the power of Dependency Injection in our application.

让我们分析一下如何使用Dagger和上述注释在应用程序中引入依赖注入的功能。

To instantiate the SharedPreferences instance in another class, we need to pass the current context.
The Component does the work of passing the stuff to the Module class and Injects the dependency in our Activity.

要在另一个类中实例化SharedPreferences实例,我们需要传递当前上下文。
组件完成将东西传递给Module类的工作,并将依赖项注入到我们的Activity中。

Android Dagger 2代码 (Android Dagger 2 Code)

Let’s look at the activity_main.xml layout first.

首先让我们看一看activity_main.xml布局。

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="https://schemas.android.com/apk/res/android"xmlns:app="https://schemas.android.com/apk/res-auto"xmlns:tools="https://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"tools:context="com.journaldev.dagger2.MainActivity"><EditTextandroid:id="@+id/inUsername"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_margin="8dp"android:hint="Username" /><EditTextandroid:id="@+id/inNumber"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_below="@+id/inUsername"android:layout_margin="8dp"android:inputType="number"android:hint="Number" /><Buttonandroid:id="@+id/btnSave"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="SAVE"android:layout_below="@+id/inNumber"android:layout_toLeftOf="@+id/btnGet"android:layout_toStartOf="@+id/btnGet"android:layout_marginRight="8dp"android:layout_marginEnd="8dp" /><Buttonandroid:id="@+id/btnGet"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="GET"android:layout_below="@+id/inNumber"android:layout_alignRight="@+id/inNumber"android:layout_alignEnd="@+id/inNumber" /></RelativeLayout>

The code for the SharedPrefModule.java class is given below.

下面给出了SharedPrefModule.java类的代码。

package com.journaldev.dagger2;import android.content.Context;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;
import javax.inject.Singleton;
import dagger.Module;
import dagger.Provides;@Module
public class SharedPrefModule {private Context context;public SharedPrefModule(Context context) {this.context = context;}@Singleton@Providespublic Context provideContext() {return context;}@Singleton@Providespublic SharedPreferences provideSharedPreferences(Context context) {return PreferenceManager.getDefaultSharedPreferences(context);}
}

The context is set in the constructor itself. Methods that return the dependent object are typically prepended with provide, hence the name provideSharedPreferences().

context是在构造函数中设置的。 返回依赖对象的方法通常以provideSharedPreferences() ,因此命名为provideSharedPreferences()

The code for the MyComponent.java interface is given below.

下面给出了MyComponent.java接口的代码。

package com.journaldev.dagger2;import javax.inject.Singleton;
import dagger.Component;@Singleton
@Component(modules = {SharedPrefModule.class})
public interface MyComponent {void inject(MainActivity activity);
}

All the modules are mentioned inside the @Component annotation.
The activities, services, or fragments that are allowed to request the dependencies declared by the modules (using @Inject) should be declared in this interface with individual inject() methods.

@Component批注中提到了所有模块。
允许请求模块声明的依赖项的活动,服务或片段(使用@Inject )应在此接口中使用单独的inject()方法进行声明。

The code for the MainActivity.java class is given below:

MainActivity.java类的代码如下:

package com.journaldev.dagger2;import android.content.SharedPreferences;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;import javax.inject.Inject;public class MainActivity extends AppCompatActivity implements View.OnClickListener {EditText inUsername, inNumber;Button btnSave, btnGet;private MyComponent myComponent;@InjectSharedPreferences sharedPreferences;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);initViews();myComponent = DaggerMyComponent.builder().sharedPrefModule(new SharedPrefModule(this)).build();myComponent.inject(this);}private void initViews() {btnGet = findViewById(R.id.btnGet);btnSave = findViewById(R.id.btnSave);inUsername = findViewById(R.id.inUsername);inNumber = findViewById(R.id.inNumber);btnSave.setOnClickListener(this);btnGet.setOnClickListener(this);}@Overridepublic void onClick(View v) {switch (v.getId()) {case R.id.btnGet:inUsername.setText(sharedPreferences.getString("username", "default"));inNumber.setText(sharedPreferences.getString("number", "12345"));break;case R.id.btnSave:SharedPreferences.Editor editor = sharedPreferences.edit();editor.putString("username", inUsername.getText().toString().trim());editor.putString("number", inNumber.getText().toString().trim());editor.apply();break;}}
}

The code to bind Dagger into our application is:

将Dagger绑定到我们的应用程序中的代码是:

myComponent = DaggerMyComponent.builder().sharedPrefModule(new SharedPrefModule(this)).build();

Dagger keyword is prepended on the Component class name. If the component class name was AppComponent, the result would have been DaggerAppComponent.

Dagger关键字位于Component类名称的前面。 如果组件类名称为AppComponent ,则结果将为DaggerAppComponent

The Module class name is converted into camel case format and the Module is initialized inside it by passing the context(which is eventually required by the SharedPreferences to initialize!).

将模块类名称转换为驼峰格式,并通过传递上下文在模块内部对其进行初始化(最终由SharedPreferences要求进行初始化!)。

At this stage Dagger can generate files, so you need to Rebuild your project to allow it to do its job (Build > Rebuild Project).

在此阶段,Dagger可以生成文件,因此您需要重建项目以使其能够执行其工作(“构建”>“重建项目”)。

The SharedPreferences dependency object is available to use after this: myComponent.inject(this).

之后可以使用SharedPreferences依赖项对象: myComponent.inject(this)

We are able to operate upon our SharedPreferences, without the need to initialize it within the Activity.

我们能够对SharedPreferences进行操作,而无需在Activity中对其进行初始化。

We can do the same with Retrofit adapters etc to make our code simpler and easier to use/test.

我们可以对Retrofit适配器等做同样的事情,以使我们的代码更简单,更易于使用/测试。

The output of the above application is given below:

以上应用程序的输出如下:

Instead of @Singleton, we can define different Scopes too, such as @PerApp, @PerActivity to let the number of instance creations depend upon the lifetime of Application/Activity respectively.

代替@Singleton ,我们也可以定义不同的范围,例如@PerApp@ PerActivity ,以使实例创建的数量分别取决于Application / Activity的生存期。

This brings an end to android dependency injection tutorial. There’s a lot more to Dagger 2 that we’ll discuss in later tutorials. You can download the final Android Dagger2 Project from the link below.

这就结束了android依赖注入教程。 Dagger 2还有很多,我们将在以后的教程中讨论。 您可以从下面的链接下载最终的Android Dagger2项目

Download Android Dependency Injection Dagger 2 Example Project下载Android依赖注入Dagger 2示例项目

Reference: Dagger Docs

参考: Dagger文档

翻译自: https://www.journaldev.com/16758/android-dependeny-injection-dagger

dagger2 注入

dagger2 注入_Android依赖注入– Dagger 2相关推荐

  1. java依赖注入_Java依赖注入选项

    java依赖注入 我想花一些时间来总结一些流行的Java依赖注入(DI)框架. 这是可用功能的高级概述. 首先,什么是依赖注入? "依赖注入是一种软件设计模式,可以删除硬编码的依赖,并可以在 ...

  2. 依赖注入?依赖注入是如何实现解耦的?

    如何用最简单的方式解释依赖注入?依赖注入是如何实现解耦的? 第一章:小明和他的手机 从前有个人叫小明 小明有三大爱好,抽烟,喝酒-- 咳咳,不好意思,走错片场了.应该是逛知乎.玩王者农药和抢微信红包 ...

  3. 【IOC 控制反转】Android 事件依赖注入 ( 事件依赖注入具体的操作细节 | 创建 事件监听器 对应的 动态代理 | 动态代理的数据准备 | 创建调用处理程序 | 创建动态代理实例对象 )

    文章目录 前言 一.创建 事件监听器 对应的 动态代理 二.动态代理 数据准备 三.动态代理 调用处理程序 四.动态代理 实例对象创建 前言 Android 依赖注入的核心就是通过反射获取 类 / 方 ...

  4. 【IOC 控制反转】Android 事件依赖注入 ( 事件依赖注入具体的操作细节 | 获取要注入事件的 View 对象 | 通过反射获取 View 组件的事件设置方法 )

    文章目录 前言 一.获取要注入事件的 View 对象 二.通过反射获取 View 组件的事件设置方法并执行 前言 Android 依赖注入的核心就是通过反射获取 类 / 方法 / 字段 上的注解 , ...

  5. 【IOC 控制反转】Android 事件依赖注入 ( 事件依赖注入具体的操作细节 | 获取 Activity 中的所有方法 | 获取方法上的注解 | 获取注解上的注解 | 通过注解属性获取事件信息 )

    文章目录 前言 一.获取 Activity 中的所有方法 二.获取方法上的注解 三.获取注解上的注解 四.通过注解属性获取相关事件信息 前言 Android 依赖注入的核心就是通过反射获取 类 / 方 ...

  6. 【IOC 控制反转】Android 事件依赖注入 ( 事件依赖注入代码示例 )

    文章目录 总结 一.Android 事件依赖注入示例 1.创建依赖注入库 2.声明注解 (1).修饰注解的注解 (2).修饰方法的注解 3.Activity 基类 4.动态代理类调用处理程序 5.依赖 ...

  7. 【IOC 控制反转】Android 视图依赖注入 ( 视图依赖注入步骤 | 视图依赖注入代码示例 )

    文章目录 总结 一.Android 视图依赖注入步骤 二.Android 布局依赖注入示例 1.创建依赖注入库 2.声明注解 3.Activity 基类 4.依赖注入工具类 5.客户端 Activit ...

  8. spring依赖注入_Spring依赖注入

    spring依赖注入 介绍: 在设计良好的Java应用程序中,这些类应尽可能独立. 这样的设计提高了组件的可重用性. 它还使对各个组件进行单元测试变得更加容易. 依赖注入的概念促进了Java对象之间的 ...

  9. angular依赖注入_Angular依赖注入简介

    angular依赖注入 by Neeraj Dana 由Neeraj Dana In this article, we will see how the dependency injection of ...

最新文章

  1. python orm peewee
  2. 《机器学习实战》第十三章 PCA
  3. ZeroMq的研究和使用
  4. ubuntu-18.10 允许 root登录图形界面
  5. 计算机辅助翻译 教学大纲,计算机辅助翻译本科课程教学大纲翻译本科.doc
  6. 阿里云服务器遭ddos攻击防御案例
  7. 【寻工记】-上班第一天
  8. python:在指定范围内按学号随机生成座位顺序,并分行输出
  9. 如何使用爬虫与JieBa库制作词云
  10. 制作JavaCV应用依赖的基础Docker镜像(CentOS7+JDK8+OpenCV4)
  11. excel更改页眉页脚_如何在Excel的页眉和页脚中键入“&”号
  12. Nat.Mach.Intell.|如何改进错义突变致病性预测?使用图注意神经网络试试
  13. 【技术宅小伙】Git版本控制系统的使用
  14. sailfish:不需要比对的转录本定量软件
  15. opera 浏览器头 不是opera 打头
  16. 响应式编程之Spring Webflux
  17. 微信充值页面开发总结
  18. C#格式化JSON数据
  19. 我的PhoneGap安装配置经历
  20. matlab虚数的模,matlab计算带有复数的函数,最后求复数函数的模,结果里面却有...

热门文章

  1. 匹马行天下之思维决定高度篇——教你如何爱上“编程妹子”
  2. POJ3264(分桶法)
  3. eros --- Windows Android真机调试
  4. 检测邮箱和手机号是否正确的正则
  5. ajax的原理和运行机制
  6. Lanenet论文解读
  7. stl之multimap容器
  8. java encode乱码_java 中文乱码问题的解决
  9. java写dnf_【DNF 增幅器 JAVA 模拟增幅代码】
  10. python local global_Python 变量作用域 LEGB (上)—— Local,Global,Builtin