dagger2簡(jiǎn)單應(yīng)用用一個(gè)mvp架構(gòu)來(lái)做例子
apt編譯時(shí)生成代碼
apt自動(dòng)生成代碼 再為dagger2提供注入
本博客說(shuō)的是采用dagger2來(lái)搭建一個(gè)簡(jiǎn)單的mvp架構(gòu)
文章分這么幾個(gè)部分。
- 首先是說(shuō)下mvp的架構(gòu)
- 然后是 dagger的使用
- 最后是采用dagger2完成注入搭建mvp架構(gòu)
由于重點(diǎn)是dagger2.網(wǎng)絡(luò)部分不做封裝了,一般都是采用rxjava+retrofit。這個(gè)需要結(jié)合自己實(shí)際情況,不是一套后臺(tái),封裝的也是不一樣的。
第一部分mvp架構(gòu)
mvp估計(jì)大家都很清楚,我就不廢話。這里采用簡(jiǎn)化的view 和presenter ,項(xiàng)目實(shí)在用不到m層。。activity 和fragment負(fù)責(zé)ui, presenter 負(fù)責(zé)加載數(shù)據(jù),網(wǎng)絡(luò)請(qǐng)求,然后加載完數(shù)據(jù)通過(guò)接口回掉給 activity 和fragment。這樣就 是一個(gè)簡(jiǎn)單的mvp架構(gòu)。減輕了activity壓力
第二部分dagger2使用簡(jiǎn)單介紹
dagger2的原理和詳細(xì)已經(jīng)有很多文章寫(xiě)的很好了。我這就簡(jiǎn)單說(shuō)下怎么用就好了。
首先有這么幾個(gè)東西,Component Module 和scope。這三個(gè)東西 是一套完整的注入。application級(jí)別的Component 需要在application里面初始化,activity級(jí)別的需要在activity里面初始化,fragment同activity一樣
首先引入包
compile 'com.google.dagger:dagger:2.7'
provided 'com.google.dagger:dagger-compiler:2.6.1'
Scope Module Component
- 先說(shuō)最簡(jiǎn)單的scope
scope是用來(lái)標(biāo)注作用范圍,作用域,在provider方法寫(xiě)上,這個(gè)注解
application一般是全局單例模式的,所以Socope用dagger2自帶的Singleton就好了
其他的 Socope自己定義就好,比如activity 的
@Scope
public @interface ActivityScope {
}
就是這么簡(jiǎn)單。
- 說(shuō)完scope創(chuàng)建Module
modeule作用就是創(chuàng)建你的實(shí)例。依賴(lài)注入也要有地方來(lái)創(chuàng)建你的實(shí)例才行吧,對(duì)就是module。
Module其實(shí)是一個(gè)簡(jiǎn)單工廠模式,Module里面的方法基本都是創(chuàng)建類(lèi)實(shí)例的方法。 但是 ,自己的類(lèi)不是三方的,可以不用創(chuàng)建,只需要你把需要實(shí)例化的對(duì)象的構(gòu)造方法 用inject標(biāo)注,module里面一個(gè)方法用Provides 來(lái)標(biāo)注,那么這個(gè)方法返回值就是 inject標(biāo)注的構(gòu)造方法的參數(shù),dagger2會(huì)自己初始化這個(gè)被inject標(biāo)注的構(gòu)造方法看個(gè)例子
@Module
public class TestModule {
public TestModule(Activity a) {
}
@Provides
@ActivityScope//自定義的soupe
public String provideBindMobActivity() {
return new String("xx");
}
public class Student {
private String name;
@Inject
public Student(String name) {
this.name = name;
}
}
最后是使用
@inject
Student xiaoming;
就有有一個(gè)xiaoming的student實(shí)例了。
總結(jié)一下就是 ,新建一個(gè)module需要添加類(lèi)注解module,這樣dagger2就知道這是一個(gè)module了。
student的構(gòu)造接受string 而module里面的provider方法正好返回一個(gè)string。這樣就可以匹配上,不需要寫(xiě)new就能實(shí)例化一個(gè)student。
- 最后的就是Component
是不是好奇,module怎么和inject關(guān)聯(lián)的。就是通過(guò)component這個(gè)中間件來(lái)建立連接的。
來(lái)看例子
@ActivityScope
@Component(modules = TestModule.class)
public interface Testcomponent {
void inject(Activity a)
}
規(guī)則就是這樣,先是一個(gè)scope的作用域,這個(gè)與你module上的provider方法的那個(gè)scope是對(duì)應(yīng)的。然后是這類(lèi)是一個(gè)接口,
采用Component 把module和inject來(lái)進(jìn)行了關(guān)聯(lián)。對(duì)就是這樣。 接口有個(gè)inect方法,來(lái)進(jìn)行activity注入
dagger2 就是這樣。簡(jiǎn)單了解下。下面就是dagger2和mvp的結(jié)合,后面會(huì)給出代碼
dagger2 和mvp結(jié)合
上面的mvp架構(gòu),需要new new new 采用dagger2依賴(lài)注入厚,不需要在new。
首先是dagger2的app級(jí)別的初始化。還是分三個(gè)部分
Module
@Module
public class AppModule {
private Application application;
public AppModule(Application application) {
this.application = application;
}
}
Component
@Singleton
@Component(modules = AppModule.class)
public interface Appcomponent {
}
以及注入初始化代碼。 app級(jí)別的當(dāng)然在application里面出初始化
public class MyApplication extends Application {
private static MyApplication mInst;
private Appcomponent mAppcomponent;
@Override
public void onCreate() {
super.onCreate();
mInst = this;
mAppcomponent = DaggerAppcomponent. //Dagger +自己定義的component名字
builder()
.appModule(new AppModule(this)) // 自己定義的App級(jí)別Module的名字
.build();
}
public static MyApplication getInst() {
return mInst;
}
public Appcomponent getAppComponent() {
return mAppcomponent;
}
}
完成app級(jí)別的初始化,就可以繼續(xù)activity級(jí)別的。 還是三部分
module 的構(gòu)造接受一個(gè)activity,然后provider直接返回
@Module
public class ActivityModule {
BaseMVPActivity activity;
public ActivityModule(BaseMVPActivity activity) {
this.activity = activity;
}
@Provides
@ActivityScope
public BaseMVPActivity provideBindMobActivity() {
return activity;
這個(gè) 的 Component dependencies了一個(gè)app的,這點(diǎn)像繼承關(guān)系,可以用app里面的,自己的是 ActivityModule。
@ActivityScope
@Component(dependencies = Appcomponent.class,
modules = ActivityModule.class)
public interface Activitycomponent {
void inject(MainActivity activity);
// 可以公用一個(gè)Component
// void inject(SecondActivity activity);
// void inject(Tread activity);
}
最后一步是初始化注入 在activity自然寫(xiě)在activity里面
這里寫(xiě)在抽象父類(lèi)里面
public abstract class BaseMVPActivity<P extends BasePresenter> extends AppCompatActivity implements BaseMvpViewInterface {
@Inject//與Presenter 構(gòu)造的方法的inject注解對(duì)應(yīng)。自動(dòng)注入
protected P mvpPresenter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
initInject(DaggerActivitycomponent.builder()
.appcomponent(MyApplication.getInst().getAppComponent())
.activityModule(new ActivityModule(this))
.build());
mvpPresenter.attachView(this);
}
protected abstract void initInject(Activitycomponent activityComponent);
@Override
protected void onDestroy() {
super.onDestroy();
if (mvpPresenter != null) {
mvpPresenter.detachView();
}
}
}
public class MainActivity extends BaseMVPActivity<MainAcPresenter> implements MainAcView {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mvpPresenter.loadData();
}
@Override
protected void initInject(Activitycomponent activityComponent) {
activityComponent.inject(this);
}
@Override
public void loadSucess(String string) {
Toast.makeText(this, string, Toast.LENGTH_SHORT).show();
}
@Override
protected void onDestroy() {
super.onDestroy();
mvpPresenter.detachView();
}
}
抽象父類(lèi)個(gè)抽象方法,來(lái)注入子類(lèi),用inject標(biāo)注的preseter就不需要在new了。
就是這個(gè)樣子。每當(dāng)新建mvp的activity也不需要過(guò)過(guò)多操作,
只要實(shí)現(xiàn)一下 父類(lèi)抽象方法,注入一下就可以了。