1. 程式人生 > >Android Dagger (一) Inject、Module、Component、使用及原理

Android Dagger (一) Inject、Module、Component、使用及原理

前言

首先推薦一些文章

dagger2 相比其他框架入門成本較高,但是因業務複雜,我們還是學習下

推薦文章

Android_Dagger2篇——從小白最易上手的角度

demo

宣告 inject

public class Car {
    @Inject
    Person person;

    @Inject
    public Car(){
    }

    public String go(){
        return person.getName() + " -> 這車是我的";
    }
}

宣告 module

@Module
public class DemoModule {
    @Provides
    Person providePerson(){
        return new Person();
    }
}

宣告 component

@Component(modules = DemoModule.class)
public interface DemoComponent {
    void inject(DemoActivity activity);
}

在 DemoActivity 使用

請先rebuild, 下面我們將會講解原理

public
class DemoActivity extends AppCompatActivity { @Inject Person person; @Inject Car car; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_demo); DaggerDemoComponent.create().inject(this
); // 顯示結果 // person -> Person{name="張三",age = 13} // car -> 張三 -> 這車是我的 ((TextView)findViewById(R.id.tv_content)).setText( "person -> " + person.toString() + "\n" + "car -> " + car.go() ); } }

原理分析

原始碼路徑

app/build/generated/source/kapt

上面那些程式碼就完成了最基本的依賴注入,是不是覺得很神奇,那麼我們先看原始碼分析一波

如果不看最基本的原理分析,後面的教程將會雲裡霧裡的,至少我是~現在開始進入正題

先公佈答案,因為大腦先有個藍圖

瞭解區別

DaggerDemoComponent.create().inject(this);
// create 方法其實內部是
new Builder().build()  // 稍微記下,後面需要理解

inject

如果 上面的 Car類不傳例項

// 在程式碼中構建 將會變為
  private DemoActivity injectDemoActivity(DemoActivity instance) {
    // MembersInjector我們後面再解釋
    // 對的 如果無參 Car 就是簡單直接new 並 賦值給 DemoActivity 成員變數 car
    DemoActivity_MembersInjector.injectCar(instance, new Car());
    return instance;
  }

當然我們是傳值的,而且這個值來之 Module 註解, 看完後面我們就知道了

module

class DaggerDemoComponent{
  ...
  public static final class Builder {
    private DemoModule demoModule;

    private Builder() {}

    // 上面build時
    public DemoComponent build() {
      if (demoModule == null) {
      // 對的這裡直接建立了
        this.demoModule = new DemoModule();
      }
      return new DaggerDemoComponent(this);
    }

    public Builder demoModule(DemoModule demoModule) {
      this.demoModule = Preconditions.checkNotNull(demoModule);
      return this;
    }
  }
}

對的直接new了,就這麼簡單? 當然不是
還記得我們 module 裡面 provide 對外提供的方法嗎

編譯出了 DemoModule_ProvidePersonFactory.java
因為我們 provide了一個方法,如果是多個方法,當然就是多個類了
格式 模組名_方法名Factory,如 DemoModule_ProvidePersonFactory

public final class DemoModule_ProvidePersonFactory implements Factory<Person> {
  private final DemoModule module;

  public DemoModule_ProvidePersonFactory(DemoModule module) {
    this.module = module;
  }
   // 這裡面每個方法,其實最終都是 做了一樣的事情
     public static Person proxyProvidePerson(DemoModule instance) {
        // 原句不是這樣,這裡為了幫助分析,只認結果
        // 直接 呼叫了 module.providePerson()
        // 也就是 我們最早期宣告 module 提供出來的方法
        return instance.providePerson()
  } 
}

Component

class DaggerDemoComponent{
  private DemoActivity injectDemoActivity(DemoActivity instance) {
    DemoActivity_MembersInjector.injectXXXX(instance, XXXX例項)
    return instance;
  }
}

DemoActivity_MembersInjector
也就是最終負責注入的成員,操作類