文章索引
dagger2 循序漸進學習(一)依賴注入基礎知識(包會)
dagger2 循序漸進學習(二)
dagger2 循序漸進學習(三) 實例1,application中的應用
昨天寫了關(guān)于dagger2 的重要但比較易于理解的基礎知識 依賴注入豪墅,這里是鏈接dagger2 循序漸進學習(一)依賴注入基礎知識判呕。
今天這篇就開始主要講dagger2 本身了改执,遵循循序漸進簡單易懂的原則体谒,所以要花費一定篇幅填抬。
那么首先要明確了解一下dagger2是什么:
Dagger1
這個版本不是這篇文章的重點,所以我只是簡略地說一下辆童。不管怎樣宜咒,Dagger1還是做了很多的貢獻,可以說是如今Android上最流行的依賴注入框架把鉴。它是由Square公司受到Guice啟發(fā)創(chuàng)建的故黑。
基本特點:
多個注入點:依賴,通過injected
多種綁定方法:依賴庭砍,通過provided
多個modules:實現(xiàn)某種功能的綁定集合
多個對象圖: 實現(xiàn)一個范圍的modules集合
Dagger1是在編譯的時候?qū)嵭薪壎ǔ【В贿^也用到了反射機制。但這個反射不是用來實例化對象的怠缸,而是用于圖的構(gòu)成诗轻。Dagger會在運行的時候去檢測是否一切都正常工作,所以使用的時候會付出一些代價:偶爾會無效和調(diào)試困難揭北。
Dagger2
Dagger2是Dagger1的分支扳炬,由谷歌公司接手開發(fā),目前的版本是2.0搔体。Dagger2是受到AutoValue項目的啟發(fā)恨樟。 剛開始,Dagger2解決問題的基本思想是:利用生成和寫的代碼混合達到看似所有的產(chǎn)生和提供依賴的代碼都是手寫的樣子疚俱。
如果我們將Dagger2和1比較劝术,他們兩個在很多方面都非常相似,但也有很重要的區(qū)別计螺,如下:
再也沒有使用反射:圖的驗證夯尽、配置和預先設置都在編譯的時候執(zhí)行。
容易調(diào)試和可跟蹤:完全具體地調(diào)用提供和創(chuàng)建的堆棧
更好的性能:谷歌聲稱他們提高了13%的處理性能
代碼混淆:使用派遣方法登馒,就如同自己寫的代碼一樣
當然所有這些很棒的特點都需要付出一個代價匙握,那就是缺乏靈活性,例如:Dagger2沒用反射所以沒有動態(tài)機制陈轿。
是不是蒙蔽了??!!
廢話少說圈纺,上代碼,來看下如何找Android 中使用dagger2麦射。
首先在整個項目的gradle文件中加入即時編譯生成代碼的apt插件依賴(或者也可以寫到下面moudel的gradle文件中)
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:2.2.3'
classpath 'com.neenbedankt.gradle.plugins:android-apt:1.4'//這里是添加的蛾娶,也可以寫到下面moudel的gradle文件中
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
jcenter()
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
然后在moudel的gradle文件中加入相關(guān)依賴:
apply plugin: 'com.android.application'
apply plugin: 'com.neenbedankt.android-apt' //加入即時編譯插件apt
android {
compileSdkVersion 25
buildToolsVersion "25.0.2"
defaultConfig {
applicationId "zhangzhe.daggerdemo"
minSdkVersion 15
targetSdkVersion 25
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
compile 'com.android.support:appcompat-v7:25.1.0'
testCompile 'junit:junit:4.12'
apt 'com.google.dagger:dagger-compiler:2.0'//這里是添加的
compile 'com.google.dagger:dagger:2.0'//這里是添加的
provided 'javax.annotation:jsr250-api:1.0'//這里是添加的
}
先不講dagger2的理論一些名稱直接擼代碼;
以Android當前流行的mvp模式為例潜秋,寫一個簡要的登錄demo蛔琅。
1.先建立登錄的activity 作為view層;
public class LoginActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
}
}
2.建立ILoginContract協(xié)議接口峻呛,定義view層和presenter層的邏輯罗售。
public interface ILoginContract {
interface ILoginPresenter {
void login(String name,String pwd);
}
interface ILoginView<ILoginPresenter>{
void loginok();
void loginErro();
}
}
3.建立presenter的實現(xiàn)類
public class LoginPresenter implements ILoginContract.ILoginPresenter {
ILoginContract.ILoginView view;
public LoginPresenter(ILoginContract.ILoginView view) {
this.view = view;
}
@Override
public void login(String name, String pwd) {
}
}
我們按常規(guī)的方式會把LoginPresenter 在activity中聲明成員變量辜窑,并new 出來如下:
public class LoginActivity extends AppCompatActivity implements ILoginContract.ILoginView{
LoginPresenter presenter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
presenter = new LoginPresenter(this);//這里有問題
}
@Override
public void loginok() {
}
@Override
public void loginErro() {
}
}
如上,這里的presenter是new出來的寨躁,達到互相依賴的關(guān)系穆碎,這樣就把彼此僅僅的耦合在一起了,一旦presenter的構(gòu)造方法改變就要同時改變activity中的代碼职恳,這不是我們想要的所禀。
那么dagger2 是如何注入的呢;
首先我們需要新建兩個類文件:
Moudule類
@Module
public class LoginMoudule {
private final ILoginContract.ILoginView view;
public LoginMoudule(ILoginContract.ILoginView view) {
this.view = view;
}
@Provides
ILoginContract.ILoginView provideLoginView(){
return view;
}
}
Component類
@Component(modules = LoginMoudule.class)
public interface LoginComponent {
void inject(LoginActivity activity);
}
可見moudule類用@Module 注解放钦,構(gòu)造方法中注入view層色徘, 并用@Provides注解一個返回ILoginView的方法;Component類用@Component(modules = LoginMoudule.class)注解可見Component與LoginMoudule.class必然存在某種關(guān)系操禀,并inject方法把activity聯(lián)系起來贺氓,這樣這幾個類就肯定通過某種方法聯(lián)系起來了,但這些聯(lián)系并不需要我們程序員去寫什么了床蜘。
接下來就是對view和presenter兩個類內(nèi)部進行改造:activity
public class LoginActivity extends AppCompatActivity implements ILoginContract.ILoginView{
@Inject//這里加注解
LoginPresenter presenter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
}
@Override
public void loginok() {
}
@Override
public void loginErro() {
}
}
presenter類
public class LoginPresenter implements ILoginContract.ILoginPresenter {
ILoginContract.ILoginView view;
@Inject//這里注解
public LoginPresenter(ILoginContract.ILoginView view) {
this.view = view;
}
@Override
public void login(String name, String pwd) {
}
}
在activity中的依賴的presenter添加@Inject注解,同時在presenter中的構(gòu)造方法同時加這個@Inject的注解蔑水,之后build一下整個項目邢锯,在項目的project視圖下的build的文件夾下生成了如下的幾個類,這就是dagger2 通過apt生成的輔助類搀别,也是dagger2的玄機所在丹擎。
回到activity中:
public class LoginActivity extends AppCompatActivity implements ILoginContract.ILoginView{
@Inject
ILoginContract.ILoginPresenter presenter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
//添加此句
DaggerLoginComponent.builder().loginMoudule(new LoginMoudule(this)).build().inject(this);
}
@Override
public void loginok() {
}
@Override
public void loginErro() {
}
}
dagger2生成的義Dagger前綴的Component內(nèi)部完成了這一系列注入過程。
到此為止mvp中v和p的互相注入通過dagger2已經(jīng)完成歇父,此時可以測試一下蒂培,看presenter是否會報空指針。你可能會說了榜苫,wtf(what the fuck)這么麻煩;ご痢!呵呵垂睬,和我一開始一樣的媳荒。但是想想框架不一定就是能滿足程序員的懶,框架麻煩但是能讓我們的程序更健壯驹饺,或者維護起來會省很多事扒怼!想你說的 赏壹,懶鱼炒!沒辦法。
好今天就到這里蝌借,接下來會詳細介紹dagger2 的細節(jié)昔瞧,每天學一點點指蚁,厚積薄發(fā)。
每天發(fā)的東西都是我正在學習的東西硬爆,學習的同時欣舵,與更多人分享,一能增進我的記憶缀磕,同時提出自己的見解與大家互相促進提高缘圈,同時也希望收到拍磚