Dagger2 Demo

.MVP模式簡介

我們的目標是實現(xiàn)MVP模式來開發(fā)我們的應用,那首先得知道什么是MVP模式。下面這篇文章講述得通俗易懂,非常適合新手學習。MVP模式簡單易懂介紹

這里簡單講一下,

M ---- model,即數(shù)據(jù)層

V ---- view,即界面層比如我們的Activity和Fragment

P ---- presenter, 即業(yè)務層,我個人覺得更像是管理層。管理數(shù)據(jù)如何顯示,管理界面如何改變數(shù)據(jù)。

這樣一來就可以避免我們的Activity承擔過多的工作,樓主之前開發(fā)中有一個Activity的代碼量到達了兩千行,一碰到那部分需求有變更我就頭大!!!真是往事不堪回首。。。

MVP作為一種相對新興的架構,要理解它也需要花一點點時間的。大家最好還是去讀一下上面提到的那篇文章,不然這篇文章你可能會懵b。。。

2.Dagger簡介

dagger的核心是依賴和注入。目的是為了讓View層與Presenter層盡可能的解耦。至于解耦的好處,無論是測試還是后續(xù)擴展功能等方面都是受益無窮的。

通俗的講就是,當你在Activity中需要使用一個類的對象P時候,你不用管P的對象如何實例化,直接就拿來用。至于這個P如何實例化,dagger會幫你搞定,只要你按照它的套路來就行了。

樓主學習dagger也是看了網(wǎng)上很多文章,終于在讀完這篇dagger2頓悟之后才開竅了。推薦大家去讀讀,里面講得很詳細從實現(xiàn)到源碼分析都有涉及。所以,那篇文章里面寫過的東西我不打算再搬運一遍了。

既然那篇文章已經(jīng)寫得那么好了,為什么我這里又要寫一篇呢?

一來樓主看了很多篇文章都很懵B,當時就暗暗決定懂了之后一定要自己總結一番

二來每個人的思考方式都不同,說不定有些人思維方式跟我差不多,那么我的總結就更對他們的胃口,可以少走彎路了。

好了,廢話講完,來看例子。

3.使用dagger的實例

這是一個很小的mvp項目,主要是講解一下dagger的使用流程。從這個項目中,你是體會不到mvp的好處的。

首先,需求是 點擊一個button,程序就更新textView中的內容。就像這樣:

其實實現(xiàn)這個功能,只需要短短幾句代碼就可以搞定的。但是我們今天的目的是使用dagger,所以先不忙,想想怎樣通過dagger來實現(xiàn)這個功能。

3.1 引入dagger2到新建的項目

先在project的build.gradle文件中添加一個插件依賴 Android-apt

[java] view plain copy 在CODE上查看代碼片派生到我的代碼片
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:2.1.2'
classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}

然后在app/build.gradle文件中添加dagger庫和相關依賴,下面是完整的app/build.gradle文件
[java] view plain copy 在CODE上查看代碼片派生到我的代碼片
apply plugin: 'com.android.application'
apply plugin: 'com.neenbedankt.android-apt'

android {
compileSdkVersion 23
buildToolsVersion "23.0.2"

defaultConfig {  
    applicationId "k.javine.mvpprojectex"  
    minSdkVersion 19  
    targetSdkVersion 23  
    versionCode 1  
    versionName "1.0"  
}  
buildTypes {  
    release {  
        minifyEnabled false  
        proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'  
    }  
}  

}

dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
testCompile 'junit:junit:4.12'
compile 'com.android.support:appcompat-v7:23.2.1'
compile 'com.google.dagger:dagger:2.2'
apt 'com.google.dagger:dagger-compiler:2.2'
compile 'org.glassfish:javax.annotation:10.0-b28'
compile 'com.jakewharton:butterknife:7.0.1'
}
大家注意頂部的
[java] view plain copy 在CODE上查看代碼片派生到我的代碼片
apply plugin: 'com.neenbedankt.android-apt'
和底部的
[java] view plain copy 在CODE上查看代碼片派生到我的代碼片
compile 'com.google.dagger:dagger:2.2'
apt 'com.google.dagger:dagger-compiler:2.2'
compile 'org.glassfish:javax.annotation:10.0-b28'
就可以了,我習慣性的使用了butterKnife庫,本人非常喜歡這個東西。
好了,引入dagger2成功了。

3.2 項目結構

簡單說一下:

a. IPresenter和IView兩個接口,如果你了解了MVP模式就會明白它們的作用。主要是為了讓VIEW層和Presenter層的解耦

[java] view plain copy 在CODE上查看代碼片派生到我的代碼片
public interface IView {
/**
* 更新UI
* @param data
*/
void updateUi(String data);
}

[java] view plain copy 在CODE上查看代碼片派生到我的代碼片
public interface IPresenter {
/**
* 加載數(shù)據(jù)
*/
void loadData();
}

b. MyPresenter實現(xiàn)IPresenter接口(在此項目中IPresenter基本沒用到,算我偷懶了),此類將被dagger注入到MainActivity中去。

[java] view plain copy 在CODE上查看代碼片派生到我的代碼片
public class MyPresenter implements IPresenter{
private IView mainView;

public MyPresenter(IView view){  
    mainView = view;  
}  


@Override  
public void loadData() {  
    mainView.updateUi("Mvp Update UI "+System.currentTimeMillis());  
}  

}

c. MyModule類 用來提供依賴,里面定義一些用@Provides注解的以provide開頭的方法。MainActivity中使用的MyPresenter對象就是在此處被實例化的。

[java] view plain copy 在CODE上查看代碼片派生到我的代碼片
@Module
public class MyModule {

private IView mainView;  

public MyModule(IView mainView){  
    this.mainView = mainView;  
}  

@Provides  
public MyPresenter provideMyPresenter(){  
    return new MyPresenter(mainView);  
}  

}
d. AppComponent類是一種橋梁,MyPresenter類通過AppComponet注入到MainActivity中去的。我們將會在MainActivity中看到注入是通過DaggerAppComponent類來執(zhí)行的,而這是一個我從來沒有編寫過的類...它就是dagger的插件給我們自動生成的,當然是根據(jù)AppComponet來生成的。

[java] view plain copy 在CODE上查看代碼片派生到我的代碼片
@Component(modules = MyModule.class)
public interface AppComponent {
void inject(MainActivity activity);
}
e. MainActivity實現(xiàn)IView接口,這樣MyPresenter就可以通過IView引用實例來控制View層的改變。

[java] view plain copy 在CODE上查看代碼片派生到我的代碼片
public class MainActivity extends AppCompatActivity implements IView, View.OnClickListener {

@Bind(R.id.result)  
TextView tv_result;  
@Bind(R.id.btn_update)  
Button btn_update;  

@Inject  
MyPresenter myPresenter; //獲取依賴的對象  

@Override  
protected void onCreate(Bundle savedInstanceState) {  
    super.onCreate(savedInstanceState);  
    setContentView(R.layout.activity_main);  
    ButterKnife.bind(this);  
    btn_update.setOnClickListener(this);  
    DaggerAppComponent.builder()       
            .myModule(new MyModule(this))  
            .build()  
            .inject(this); //注入  
}  

@Override  
public void updateUi(String data) {  
    tv_result.setText(data);  
}  

@Override  
public void onClick(View v) {  
    switch (v.getId()){  
        case R.id.btn_update:  
            myPresenter.loadData();  
            break;  
    }  
}  

}

每一步的代碼都很簡單,最好是自己新建一個項目來跑一遍這個流程。
這樣一來,就算業(yè)務邏輯再復雜,都可以丟到presenter層去處理,activity只需要實現(xiàn)updateUi()方法和一些UI事件的處理即可。

presenter層處理完數(shù)據(jù)之后,通過IView對象調用updateUi()方法將數(shù)據(jù)展示出來。

樓主本人現(xiàn)在也是個MVP的初學者,寫這篇文章的時候還有很多沒想明白的問題,有興趣可以一起討論討論。

對了,dagger生成的代碼是值得去讀一讀的,可以幫助我們深入了解dagger的原理,位置在這里

注:圖中的MainActivity$$ViewBinder類是ButterKnife框架生成的。
2

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容