我们知道java的多态支持声明一个父类对象,然后实例化一个子类对象赋值给它

但是Dagger并不支持这种多态,我们可以写个例子验证下,直接上代码

public interface Person {
    String saySomething();
public class Student implements Person {
    public String name;
    // 注入的是子类
    @Inject
    public Student() {
        this.name = "野猿新一";
    @Override
    public String toString() {
        return String.format("我的名字叫%s啦", name);
    @Override
    public String saySomething() {
        return toString();
@Component
public interface MainActivityComponent {
    void inject(MainActivity activity);
public class MainActivity extends AppCompatActivity {
    // 这里声明的是父类
    @Inject
    Person student;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        DaggerMainActivityComponent.create().inject(this);
        TextView textView = findViewById(R.id.text);
        textView.setText(student.saySomething());

直接运行下,结果无法编译通过,报如下错误

error: [Dagger/MissingBinding] com.him.hisapp.Person cannot be provided without an @Provides-annotated method.
com.him.hisapp.Person is injected at
com.him.hisapp.MainActivity.student
com.him.hisapp.MainActivity is injected at
com.him.hisapp.MainActivityComponent.inject(com.him.hisapp.MainActivity)

计时用Modele也是没用的

@Module
public class MainModule {
    @Provides
    public Student providePerson() {
        return new Student();

除非我们将Modele中providePerson方法返回类型明确声明为父类Person

@Module
public class MainModule {
    @Provides
    public Person providePerson() {
        return new Student();

其实很容易知道为什么Dagger依赖注入不支持多态的原因,我们假设需要注入一个Object的对象,而项目中如果有很多@Inject标识的构造方法,这些构造方法生成的对象都是Object的子类对象,那么Dagger就不知道要注入哪一个,就无法编译通过。

我们知道java的多态支持声明一个父类对象,然后实例化一个子类对象赋值给它但是Dagger并不支持这种多态,我们可以写个例子验证下,直接上代码public interface Person { String saySomething();}public class Student implements Person { public String name;...
依赖注入这个模式(模式已经用烂了,这里再烂一次)是用来给应用的各部分解耦的。使应用开发更加可扩展,更容易维护。通过本文你会学到如何使用Dagger2来处理依赖。如果以对象需要另外的一个对象才能完成一个完整功能的话,那么这里就存在一个依赖。比如,悟空要用金箍棒才能三打白骨精,要筋斗云才能十万八千里。悟空有对金箍棒和筋斗云的依赖。你可以在悟空对象里初始化金箍棒,也可以用一个工厂方法批量生产金箍棒。使用依赖注入可以无需一个专门的来初始化这些依赖对象。这样就实现了解耦。本教程会使用最新的Dagger2(当前的版本是2.2)。这里是官网。你可以在这里找到最新的发布。AndroidStudio是必须的。
#AndroidInject 一个简单的 androd 资源注入工具,只有一个,方便拷贝,用来在平时学习中简化一些操作,减少重复代码量,因此,只适合学习工程 如果需要在工作中使用,可以参考更严谨的视图注入框架 不支持绑定继承而来的字段与方法 ##使用方法 ####绑定资源 @Injector.Res(R.string.string_1) String string_1; @Injector.Res(R.array.sa_1) String[] sa; @Injector.Res(R.integer.int_1) int int_1; @Injector.Res(R.array.ia_1) int[] ia; @Injector.Res(R.bool.bool_1) boolean bool_1; ####绑定事件 //普通View @Injector.View(R.id.btn_1) @AINoTitle: 注解, 只适用于Activity(需继承于AIActivity), 设置Activity不显示Title     @AIFullScreen: 注解, 只适用于Activity(需继承于AIActivity), 设置Activity全屏     @AILayout: 注解         value[int]: 用于设置该Activity的布局 ---- setContentView(resId);     @AIView: 属性注解         id[int]: 用于绑定控件 ---- findViewById(resId);(default identifier[R.id.{field name}] if did not set id)         clickMethod[String]: 用于设置控件点击事件的回调方法, 可选, 方法名称任意, 参数必须为(View view)         longClickMethod[String]: 用于设置控件长按的回调方法, 可选, 方法名任意, 参数必须为(View view)         itemClickMethod[String]: 用于设置控件item点击的回调方法, 可选, 方法名任意, 参数必须为(AdapterView, View, int, long)         itemLongClickMethod[String]: 用于设置控件item长按的回调方法, 可选, 方法名任意, 参数必须为(AdapterView, View, int, long)     @AIBean: 属性注解, 为该属性生成一个对象并注入, 该对象必须有个默认的不带参数的构造方法     @AISystemService: 属性注解,为该属性注入系统服务对象     @AIClick: 方法注解         value[int[], 所要绑定控件的id]: 用于绑定控件点击事件的回调方法, 方法名称任意, 参数必须为(View view)     @AIItemClick: 方法注解         value[int[], 所要绑定控件的id]: 用于绑定控件item点击事件的回调方法, 方法名称任意, 参数必须为(AdapterView, View, int, long)     @AILongClick: 方法注解         value[int[], 所要绑定控件的id]: 用于绑定控件长按事件的回调方法, 方法名称任意, 参数必须为(View view)     @AIItemLongClick: 方法注解         value[int[], 所要绑定控件的id]: 用于绑定控件item长按事件的回调方法, 方法名称任意, 参数必须为(AdapterView, View, int, long)     @AIScreenSize: 属性注解         用于注入当前设备的屏幕大小(宽高)     @AIGet: 方法注解         value[String, 所要请求的url]:表示以GET来请求url         connTimeout[int, 连接超时时间]:连接一个url的连接等待时间         soTimeout[int, response返回超时时间]:连接上一个url,获取response的返回等待时间     @AIPost: 方法注解         value[String, 所要请求的url]:表示以Post来请求url         connTimeout[int, 连接超时时间]:连接一个url的连接等待时间         soTimeout[int, response返回超时时间]:连接上一个url,获取response的返回等待时间     @AIParam: 方法参数注解         value[String, 请求的参数别名]:注入@AIGet或@AIPost注解方法的请求参数     @AINetWorker: 属性注解         注入网络请求服务     @AIUpload: 方法注解         value[String, 所要请求的url]:表示要上传的url,默认用post请求(不需要使用@AIPost注解)         connTimeout[int, 连接超时时间]:连接一个url的连接等待时间         soTimeout[int, response返回超时时间]:连接上一个url,获取response的返回等待时间         注意:使用此注解的方法参数需要包含Collection或其子类型集合 或者包含File对象 来作为要上传的文件
@Inject     @Inject支持构造函数、方法和字段注解,也可能使用于静态实例成员。可注解成员可以是任意修饰符(private,package-private,protected,public)。注入顺序:构造函数、字段,然后是方法。父类的字段和方法注入优先于子类的字段和方法,同一中的字段和方法是没有顺序的。     @Inject注解的构造函数可以是无参或多个参数的构造函数。@I...
Dagger除了可以在属性上表示@Inject注入对象外,还可以在方法上标识,如下所示 然后调用DaggerMainActivityComponent.create().inject(this)就可以注入对象了 public class MainActivity extends AppCompatActivity { // 这里不用标识 Student student;
dagger与抽象 继承、封装和多态是面向对象的三大特征,这三大特征无一不是围绕着抽象这个词展开的,但在前几篇的例子中,我们的依赖都是具体型,比如Computer、CPU、Memory,严重违反了依赖倒置原则: 模块间的依赖通过抽象发生,实现之间不发生直接的依赖关系,其依赖关系是通过接口或抽象产生的 总之,我们接下来需要加上抽象的思想,看看dagger怎样处理 现在我们将Co...
3 import android.annotation.SuppressLint; 4 import android.app.Activity; 5 import android.content.Intent; 6 import android.os.Bundle; 7 import android...
上一篇博客我们已经带大家简单的吹了一下IoC,实现了Activity中View的布局以及控件的注入,如果你不了解,请参考:Android 进阶 教你打造 Android 中的 IOC 框架 【ViewInject】 (上)。 本篇博客将带大家实现View的事件的注入。 1、目标效果 上篇博客,我们的事件的代码是这么写的: package com.zhy.zhy_xutils_test; impo...
依赖倒置原则(DIP Dependency Inverse Principle) 高层组件(抽象)不应该依赖于低层组件(细节),两者都应该依赖于抽象。抽象不应该依赖于细节,细节应该依赖于抽象。 其核心思想就是基于接口编程 控制反转(IOC Inverse of Control) 将控制权交向上层组件转移。控制反转是DIP的具体实现方式。 依赖注入(DI Dependency ...
Android进程注入概述我们平时所说的代码注入,主要静态和动态两种方式: 静态注入,针对是可执行文件,比如修改ELF,DEX文件等,相关的辅助工具也很多,比如IDA、ApkTool等; 动态注入,也可以叫进程注入,针对是进程,比如修改进程的寄存器、内存值等; 动态跟静态最大的区别是,动态不需要改动源文件,但需要高权限(通常是root权限),而且所需的技术含量更高。基本思路关键点在于让目标进加载自定
在 Kotlin 中使用 `@Inject` 注解通常与依赖注入框架一起使用,例如 Dagger 或 Koin。`@Inject` 注解用于标记需要依赖注入的属性、构造函数或方法。 如果你想使用 `@Inject` 注解来标记一个属性,你需要确保该属性已经被正确配置,并且依赖注入框架能够将相应的依赖注入到该属性中。 以下是一个使用 `@Inject` 注解标记属性的示例: ```kotlin class ExampleClass { @Inject lateinit var dependency: DependencyClass // ... 在上述示例中,`dependency` 属性被标记为需要注入的依赖项。要确保在使用该属性之前,`dependency` 被正确地注入了相应的依赖项。 请注意,使用 `@Inject` 注解需要配置依赖注入框架,并在运行时正确地初始化和注入依赖项。具体的配置和使用方法可能因所使用的依赖注入框架而有所不同。