Dagger2入門詳解

Dagger2入門詳解

@(Android)

參考文章

Dagger官網(wǎng)

Dagger Document API

從零開始的Android新項(xiàng)目4

http://www.bozhiyue.com/anroid/boke/2016/0719/273761.html


環(huán)境配置

這里以Gradle配置為例子所意,實(shí)用得是AndroidStudio:

  1. 打開project 的 build.gradle 礼仗,添加
dependencies {
        classpath 'com.android.tools.build:gradle:2.2.2'

        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files

        //dagger2
        classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'
    }
  1. 打開 app module 的 build.gradle,添加
apply plugin: 'com.android.application'
//dagger2
apply plugin: 'com.neenbedankt.android-apt'

//...

dependencies {
    //...

    //dagger2
    compile 'com.google.dagger:dagger:2.4'
    apt 'com.google.dagger:dagger-compiler:2.4'
    compile 'org.glassfish:javax.annotation:10.0-b28'
}
  1. 然后sync gradle一下,環(huán)境就配置好了馒铃,在實(shí)用dagger2的時(shí)候击纬,會(huì)自動(dòng)生成一些類,所以最好記一下 build project的快捷鍵 ctrl+F9象泵,寫好dagger代碼琼腔,然后build一下,就會(huì)自動(dòng)生成 DaggerXXX 開頭的一些類踱葛。

入門實(shí)例

好了丹莲,下面我們來看一個(gè)入門實(shí)例,實(shí)用Dagger2到底是怎么依賴注入的尸诽。

現(xiàn)在又一個(gè)Person類(這里為了簡(jiǎn)單起見)甥材,然后MainActivity中又一個(gè)成員變量person。

Person.java

public class Person {

    public Person() {
        System.out.println("a person created");
    }
}

MainActivity.java

public class MainActivity extends AppCompatActivity {

    Person person;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        person = new Person();
    }
}

如果不適用依賴注入性含,那么我們只能在MainActivity中自己new一個(gè)Person對(duì)象洲赵,然后使用。

使用依賴注入:

public class MainActivity extends AppCompatActivity {

    @Inject
    Person person;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
   }
}

在Person對(duì)象上添加一個(gè) @Inject注解商蕴,即可自動(dòng)注入對(duì)象叠萍。

那么問題來了,就一個(gè)@Inject 注解绪商,系統(tǒng)就會(huì)自動(dòng)給我創(chuàng)建一個(gè)對(duì)象? 當(dāng)然不是苛谷,這個(gè)時(shí)候我們需要一個(gè)Person類的提供者。估計(jì)叫它: MainModule

MainModule.java

@Module
public class MainModule {

    @Provides
    Person providesPerson() {
        System.out.println("a person created from MainModule");
        return new Person();
    }
}

里面兩個(gè)注解格郁,@Module@Provides腹殿,Module標(biāo)注的對(duì)象独悴,你可以把它想象成一個(gè)工廠,可以向外提供一些類的對(duì)象锣尉。那么到底提供什么對(duì)象呢充活?

@Provides標(biāo)注的方法就是提供對(duì)象的,這種方法一般會(huì)返回一個(gè)對(duì)象實(shí)例靡挥,例如上面返回一個(gè) Person對(duì)象

那么好了先紫,現(xiàn)在Perso類的提供者也有了,我們是不是可以運(yùn)行起來了暂幼。ctrol+F9 build一下項(xiàng)目筏勒,然后運(yùn)行。發(fā)現(xiàn)沒有任何輸出(如果創(chuàng)建Person對(duì)象旺嬉,會(huì)打印消息)管行。為什么了?

這個(gè)時(shí)候需要引入第3個(gè)東東邪媳,component容器捐顷。可以把它想成一個(gè)容器雨效, module中產(chǎn)出的東西都放在里面迅涮,然后將component與我要注入的MainActivity做關(guān)聯(lián),MainActivity中需要的person就可以沖 component中去去取出來徽龟。

MainComponent.java

@Component(modules = {MainModule.class})
public interface MainComponent {

    void inject(MainActivity mainActivity);
}

看到一個(gè)新注入 @Component 表示這個(gè)接口是一個(gè)容器叮姑,并且與 MainModule.class 關(guān)聯(lián),它生產(chǎn)的東西都在這里据悔。
void inject(MainActivity mainActivity); 表示我怎么和要注入的類關(guān)聯(lián)传透。這個(gè)比較抽象!這個(gè)時(shí)候我們可以 build 一下項(xiàng)目极颓。

然后在MainActivity中將component 關(guān)聯(lián)進(jìn)去:

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        MainComponent component = DaggerMainComponent.builder()
                .mainModule(new MainModule()).build();
        component.inject(this);
    }

下面就是將 MainActivity和Module通過Component關(guān)聯(lián)起來的代碼朱盐,那么這個(gè)時(shí)候系統(tǒng)看到 有一個(gè) @Inject修飾的Person,就知道在這個(gè) MainComponent中去找菠隆,并且是有 MainModule 的 Provides修飾的方法提供的兵琳。

MainComponent component = DaggerMainComponent.builder()
    .mainModule(new MainModule()).build();
component.inject(this);

然后 build 項(xiàng)目,運(yùn)行項(xiàng)目骇径,發(fā)現(xiàn)打忧 :

person from module
a person created

說明確實(shí)系統(tǒng)創(chuàng)建了對(duì)象,并且注入到MainActivity中既峡。

細(xì)心的同學(xué)會(huì)發(fā)現(xiàn)羡榴,MainComponent, MainModule, MainActivity 都是我們自己創(chuàng)建的,上面還有一個(gè) DaggerMainComponent 是上面鬼运敢?這就是你 build project 的時(shí)候校仑,dagger自己為你生成的具體的component類(我們自己定義的是MainComponent接口)忠售。感興趣的可以直接跟到代碼里面去看看。

好了迄沫,上面我們把 DI (Dependency Inject) 最基本的流程走了一遍稻扬,用到了幾個(gè)注解:

  1. @Inject
  2. @Module
  3. @Component
  4. @Provides

下面來介紹另外幾個(gè)常用的注解。

其他注解和情況

如果只有最簡(jiǎn)單的情況羊瘩,那么上面的幾個(gè)注解已經(jīng)夠了泰佳,但是其實(shí)還有很多情形,我們稍微展示幾個(gè)

單例模式 @Singleton(基于Component)

基于Component的單例模式尘吗,怎么理解呢逝她?也是是 在這個(gè)Component 對(duì)象中,一個(gè)對(duì)象是單例對(duì)象睬捶。如果又新創(chuàng)建了一個(gè)Component黔宛,那么兩個(gè)Component中的當(dāng)你對(duì)象是不一樣的。具體的看后面介紹擒贸。

上面的MainActivity代碼不變臀晃,我們?cè)僭贛ainActivity中添加一個(gè) @Inejct Person person2,并打印兩個(gè) person對(duì)象介劫,結(jié)果如下:

person from module
a person created
person from module
a person created
org.yxm.daggerlearn2.data.Person@64cf4a2
org.yxm.daggerlearn2.data.Person@899b533

發(fā)現(xiàn)person會(huì)被創(chuàng)建兩次徽惋,并且兩個(gè)person對(duì)象也不同,如果我們希望只有一個(gè) person 和 person2 都指向同一個(gè)Person對(duì)象了座韵? 使用 @Singleton 注解

兩個(gè)地方需要加:
1. MainModule.java 的 provides方法上需要添加 @Singleton 注解

@Module
public class MainModule {

    private static final String TAG = "MainModule";

    @Singleton
    @Provides
    public Person providesPerson() {
        Log.d(TAG, "person from module");
        return new Person();
    }
}
  1. MainComponent.java 類上添加
@Singleton
@Component(modules = {MainModule.class})
public interface MainComponent {

    void inject(MainActivity mainActivity);
}

再運(yùn)行险绘,發(fā)現(xiàn)只創(chuàng)建了一次,并且兩個(gè)person指向同一個(gè)對(duì)象誉碴。

person from module
a person created
org.yxm.daggerlearn2.data.Person@64cf4a2
org.yxm.daggerlearn2.data.Person@64cf4a2

需要非常注意的是:?jiǎn)卫腔贑omponent的隆圆,所以不僅 Provides 的地方要加 @Singleton,Component上也需要加翔烁。并且如果有另外一個(gè)OtherActivity,并且創(chuàng)建了一個(gè)MainComponent旨涝,也注入Person蹬屹,這個(gè)時(shí)候 MainActivity和OtherActivity中的Person是不構(gòu)成單例的,因?yàn)樗鼈兊腃omponent是不同的白华。

帶有參數(shù)的依賴對(duì)象

如果構(gòu)造Person類慨默,需要一個(gè)參數(shù)Context,我們?cè)趺醋⑷肽兀?要知道注入的時(shí)候我們只有一個(gè) @Inject 注解弧腥,并不能帶參數(shù)厦取。所以我們需要再 MainModule 中提供context,并且由 providesXXX 函數(shù)自己去構(gòu)造管搪。如:

Person.java

public class Person {

    private Context context;

    public Person(Context context) {
        Log.d(TAG, "a person created with context:"+context);
    }
}

修改MainModule.java

@Module
public class MainModule {

    private static final String TAG = "MainModule";

    private Context context;

    public MainModule(Context context) {
        this.context = context;
    }

    @Provides
    public Context providesContext() {
        return this.context;
    }

    @Singleton
    @Provides
    public Person providesPerson(Context context) {
        Log.d(TAG, "person from module");
        return new Person(context);
    }
}

這里需要強(qiáng)調(diào)的是虾攻, providesPerson(Context context)中的 context铡买,不能直接使用 成員變量 this.context,而是要在本類中提供一個(gè) Context providesContext()@Provides 方法霎箍,這樣在發(fā)現(xiàn)需要 context 的時(shí)候會(huì)調(diào)用 provideContext 來獲取奇钞,這也是為了解耦。

依賴一個(gè)組件

如果組件之間有依賴漂坏,比如 Activity 依賴 Application一樣景埃,Application中的東西,Activity要直接可以注入顶别,怎么實(shí)現(xiàn)呢谷徙?

例如,現(xiàn)在由 AppModule 提供Context對(duì)象驯绎, ActivityModule 自己無需提供Context對(duì)象完慧,而只需要依賴于 AppModule,然后獲取Context 對(duì)象即可条篷。

AppModule.java

@Module
public class AppModule {

    private Context context;

    public AppModule(Context context) {
        this.context = context;
    }

    @Provides
    public Context providesContext() {
        return context;
    }
}

AppComponent.java

@Component(modules = {AppModule.class})
public interface AppComponent {
    // 向下層提供Context
    Context getContext();
}

ActivityModule.java

@Module
public class ActivityModule {

    @Provides
    Person providePerson(Context context) {
        return new Person(context);
    }
}

ActivityComponent.java

@Component(dependencies = {AppComponent.class}, modules = {ActivityModule.class})
public interface ActivityComponent {

    void inject(MainActivity mainActivity);
}

通過上面例子骗随,我們需要注意:
1. ActivityModule 也需要?jiǎng)?chuàng)建Person時(shí)的Context對(duì)象,但是本類中卻沒有 providesContext() 的方法赴叹,因?yàn)樗ㄟ^ ActivityComponent依賴于 AppComponent鸿染,所以可以通過 AppComponent中的 providesContext() 方法獲取到Context對(duì)象。
2. AppComponent中必須提供 Context getContext(); 這樣返回值是 Context 對(duì)象的方法接口乞巧,否則ActivityModule中無法獲取涨椒。

使用方法:一定要在 activityComponent中注入 appComponent 這個(gè)它依賴的組件。我們可以看到绽媒,由于AppComponent沒有直接和 MainActivity發(fā)生關(guān)系蚕冬,所以它沒有 void inject(...);這樣的接口

AppComponent appComponent = DaggerAppComponent.builder()
        .appModule(new AppModule(this))
        .build();
ActivityComponent activityComponent = DaggerActivityComponent.builder()
        .appComponent(appComponent)
        .activityModule(new ActivityModule())
        .build();
activityComponent.inject(this);

自定義標(biāo)記 @Qualifier 和 @Named

如果Person中有兩個(gè)構(gòu)造方法,那么在依賴注入的時(shí)候是辕,它怎么知道我該調(diào)用哪個(gè)構(gòu)造方法呢囤热?

修改Person類,兩個(gè)不同的構(gòu)造方法
Person.java

public class Person {

    private static final String TAG = "Person";

    private Context context;
    private String name;

    public Person(Context context) {
        Log.d(TAG, "a person created with context:" + context);
    }

    public Person(String name) {
        this.name = name;
        Log.d(TAG, "a person created with name:" + name);
    }
}

有兩種方法可以解決這個(gè)問題:

@Named(“…”)

@Module
public class MainModule {

    private static final String TAG = "MainModule";

    private Context context;

    public MainModule(Context context) {
        this.context = context;
    }

    @Provides
    public Context providesContext() {
        return this.context;
    }

    @Named("context")
    @Provides
    public Person providesPersonWithContext(Context context) {
        return new Person(context);
    }

    @Named("string")
    @Provides
    public Person providesPersonWithName() {
        return new Person("yxm");
    }
}

分別在兩個(gè)提供Person的provides方法上添加 @Named標(biāo)簽获三,并指定旁蔼。

然后在要依賴注入的地方,同樣添加 @Name 標(biāo)注表示要注入時(shí)使用哪一種

    @Named("string")
    @Inject
    Person p1;

    @Named("context")
    @Inject
    Person p2;

@Qualifier自定義標(biāo)簽

使用@Named 會(huì)使用到 字符串 疙教,如果兩邊都必須寫對(duì)才能成功棺聊,并且字符串總是不那么優(yōu)雅的,容易出錯(cuò)贞谓,所以我們可以自定義標(biāo)簽來解決上面的問題限佩。

PersonWithContext.java

@Qualifier
@Retention(RetentionPolicy.RUNTIME)
public @interface PersonWithContext {
}

PersonWithName.java

@Qualifier
@Retention(RetentionPolicy.RUNTIME)
public @interface PersonWithName {
}

這樣就自定義了兩個(gè)標(biāo)簽,然后在剛剛所有使用到 @Named 的地方替換成我們自定義的標(biāo)簽即可:

MainModule.java

    // ...
    @PersonWithContext
    @Provides
    public Person providesPersonWithContext(Context context) {
        return new Person(context);
    }

    @PersonWithName
    @Provides
    public Person providesPersonWithName() {
        return new Person("yxm");
    }

依賴注入的地方:

    @PersonWithContext
    @Inject
    Person p1;

    @PersonWithContext
    @Inject
    Person p2;

輸入:調(diào)用了兩種構(gòu)造方法

a person created with context:org.yxm.daggerlearn2.MainActivity@8018a6e
a person created with name:yxm

懶加載Lazy和強(qiáng)制重新加載Provider

在注入時(shí)分別使用 Lazy 和 Provider 修飾要注入的對(duì)象:

@Inject
Lazy<Person> lazyPerson;

@Inject
Provider<Person> providerPerson;

在使用的地方,用 .get()方法獲人钔:

Person p1 = lazyPerson.get();
Person p2 = lazyPerson.get();
Person p3 = providerPerson.get();
Person p4 = providerPerson.get();

打印結(jié)果:

a person created with context:org.yxm.daggerlearn2.MainActivity@8018a6e
a person created with name:yxm
a person created with name:yxm

說明 lazyPerson 多次get 的是同一個(gè)對(duì)象作喘,providerPerson多次get,每次get都會(huì)嘗試創(chuàng)建新的對(duì)象耐亏。

@Scope 自定義生命周期

通過前面的例子徊都,我們遇到了 @Singleton 這個(gè)標(biāo)簽,它可以保證在同一個(gè)Component中广辰,一個(gè)對(duì)象是單例對(duì)象暇矫。其實(shí)可以跟進(jìn)去看代碼:

Singleton.java

@Scope
@Documented
@Retention(RUNTIME)
public @interface Singleton {}

就這么多東西。利用單例和組件間依賴的關(guān)系择吊,是不是我們也可以定義生命周期來滿足我們的需求呢李根?比如 Application,Activity 這樣的生命周期几睛。下面我們來創(chuàng)建這兩個(gè)生命周期:

Application生命周期
ApplicationScope.java

@Scope
@Documented
@Retention(RetentionPolicy.RUNTIME)
public @interface ApplicationScope {
}

Activity生命周期
ActivityScope.java

@Scope
@Documented
@Retention(RetentionPolicy.RUNTIME)
public @interface ActivityScope {
}

除了名字房轿,其他都和 @Singleton 是一樣的。

然后用 ApplicationScope 來修飾 AppModule和AppComponent所森,ActivityScope 修飾 ActivityModule和ActivityComponent
AppModule.java

@Module
public class AppModule {

    private Context context;

    public AppModule(Context context) {
        this.context = context;
    }

    @ApplicationScope
    @Provides
    public Context providesContext() {
        return context;
    }
}

AppComponent.java

@ApplicationScope
@Component(modules = {AppModule.class})
public interface AppComponent {

    // 向下層提供Context
    Context getContext();

}

ActivityModule.java

@Module
public class ActivityModule {

    @ActivityScope
    @PersonWithContext
    @Provides
    Person providesPersonWithContext(Context context) {
        return new Person(context);
    }

    @ActivityScope
    @PersonWithName
    @Provides
    Person providesPersonWithString() {
        return new Person("yxm");
    }
}

ActivityComponent.java

@ActivityScope
@Component(dependencies = {AppComponent.class}, modules = {ActivityModule.class})
public interface ActivityComponent {

    void inject(MainActivity mainActivity);
}

然后創(chuàng)建自定義Application:
App.java

public class App extends Application {

    public static AppComponent appComponent;

    @Override
    public void onCreate() {
        super.onCreate();

        appComponent = DaggerAppComponent.builder()
                .appModule(new AppModule(this))
                .build();
    }
}

在MainActivity中注入:

public class MainActivity extends AppCompatActivity {

    private static final String TAG = "MainActivity";

    @PersonWithContext
    @Inject
    Person p1;

    @PersonWithContext
    @Inject
    Person p2;

    @PersonWithName
    @Inject
    Person p3;

    @PersonWithName
    @Inject
    Person p4;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        ActivityComponent activityComponent = DaggerActivityComponent.builder()
                .appComponent(App.appComponent)
                .activityModule(new ActivityModule())
                .build();
        activityComponent.inject(this);

        Log.d(TAG, "" + p1);
        Log.d(TAG, "" + p2);
        Log.d(TAG, "" + p3);
        Log.d(TAG, "" + p4);

    }
}

可以看到我們注入了4個(gè)Person對(duì)象囱持,打印結(jié)果:

a person created with context:org.yxm.daggerlearn2.App@103efff
a person created with name:yxm
org.yxm.daggerlearn2.data.Person@711cc
org.yxm.daggerlearn2.data.Person@711cc
org.yxm.daggerlearn2.data.Person@a36ec15
org.yxm.daggerlearn2.data.Person@a36ec15

只創(chuàng)建了兩次,說明在ActivityScope生命周期中焕济,創(chuàng)建了兩種 Person纷妆,并且它們保持各自的單例。

其實(shí)看到這里晴弃,再說單例我都覺得不是很準(zhǔn)確了掩幢,它其實(shí)就是說的在這個(gè)Component中可以又幾個(gè)這樣的對(duì)象。如果是普通的就可能有很多個(gè)上鞠,如果是Scope修飾的际邻,就只有一個(gè)。

總結(jié)

哎喲我去芍阎,還是寫了很長(zhǎng)世曾,這篇還是主要展示了Dagger2中最基本的環(huán)境配置,和常用的標(biāo)簽以及特性,列舉一下:

  1. @Inject
  2. @Module
  3. @Component
  4. @Singleton
  5. @Scope
  6. @Named, @Qualifier
  7. Lazy, Provider
  8. modules, dependencys

然后也踩了一些坑谴咸,很無知的錯(cuò)誤:

  1. 在Component中我們會(huì)使用:void inject(實(shí)體類)度硝,表示這個(gè)Component 可以與實(shí)體類關(guān)聯(lián),然后為它注入寿冕。注意這里的實(shí)體類必須是直接關(guān)聯(lián)的那個(gè)類,如果你填它的父類椒袍,按照多態(tài)你也可以在 compoment.inject(...)的時(shí)候成功驼唱,但是卻無法注入 。糾結(jié)了好一會(huì)兒驹暑。
  2. 一旦使用 compoment.inject(...) 使某個(gè)實(shí)體類和Component發(fā)生了關(guān)系玫恳,那么對(duì)應(yīng)Component的 Module 中必須提供 @Inject修飾的所有對(duì)象的 providesXXX 方法辨赐,而且如果有兩種構(gòu)造方法,必須提供兩種 providesXXX 方法哦京办!又被坑了好一會(huì)兒掀序。
  3. 如果被依賴的 Component 使用了Scope,那么依賴他的 Component 也必須使用Scope才能使用惭婿。典型例子就是:AppComponent使用了 Scope不恭,那么ActivityComponent也必須使用Scope,否則會(huì)編譯出錯(cuò)财饥。
    轉(zhuǎn)至:http://blog.csdn.net/u013647382/article/details/53257141
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末换吧,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子钥星,更是在濱河造成了極大的恐慌沾瓦,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,378評(píng)論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件谦炒,死亡現(xiàn)場(chǎng)離奇詭異贯莺,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)宁改,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,970評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門缕探,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人透且,你說我怎么就攤上這事撕蔼。” “怎么了秽誊?”我有些...
    開封第一講書人閱讀 168,983評(píng)論 0 362
  • 文/不壞的土叔 我叫張陵鲸沮,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我锅论,道長(zhǎng)讼溺,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,938評(píng)論 1 299
  • 正文 為了忘掉前任最易,我火速辦了婚禮怒坯,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘藻懒。我一直安慰自己剔猿,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,955評(píng)論 6 398
  • 文/花漫 我一把揭開白布嬉荆。 她就那樣靜靜地躺著归敬,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上汪茧,一...
    開封第一講書人閱讀 52,549評(píng)論 1 312
  • 那天椅亚,我揣著相機(jī)與錄音,去河邊找鬼舱污。 笑死呀舔,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的扩灯。 我是一名探鬼主播媚赖,決...
    沈念sama閱讀 41,063評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼驴剔!你這毒婦竟也來了省古?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,991評(píng)論 0 277
  • 序言:老撾萬榮一對(duì)情侶失蹤丧失,失蹤者是張志新(化名)和其女友劉穎豺妓,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體布讹,經(jīng)...
    沈念sama閱讀 46,522評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡琳拭,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,604評(píng)論 3 342
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了描验。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片白嘁。...
    茶點(diǎn)故事閱讀 40,742評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖膘流,靈堂內(nèi)的尸體忽然破棺而出絮缅,到底是詐尸還是另有隱情,我是刑警寧澤呼股,帶...
    沈念sama閱讀 36,413評(píng)論 5 351
  • 正文 年R本政府宣布耕魄,位于F島的核電站,受9級(jí)特大地震影響彭谁,放射性物質(zhì)發(fā)生泄漏吸奴。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,094評(píng)論 3 335
  • 文/蒙蒙 一缠局、第九天 我趴在偏房一處隱蔽的房頂上張望则奥。 院中可真熱鬧,春花似錦狭园、人聲如沸读处。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,572評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽档泽。三九已至俊戳,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間馆匿,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,671評(píng)論 1 274
  • 我被黑心中介騙來泰國(guó)打工燥滑, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留渐北,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 49,159評(píng)論 3 378
  • 正文 我出身青樓铭拧,卻偏偏與公主長(zhǎng)得像赃蛛,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子搀菩,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,747評(píng)論 2 361

推薦閱讀更多精彩內(nèi)容

  • Dagger2入門詳解 參考文章 Dagger官網(wǎng) Dagger Document API 從零開始的Androi...
    DakerYi閱讀 1,196評(píng)論 0 7
  • 部分內(nèi)容參考自:[Android]使用Dagger 2依賴注入 - DI介紹(翻譯)[Android]使用Dagg...
    AItsuki閱讀 47,617評(píng)論 66 356
  • 什么是Dagger2 1.Dagger2是一個(gè)依賴注入框架呕臂。如果Class A 內(nèi)部 有一個(gè)Class B,我們稱...
    天天大保建閱讀 967評(píng)論 0 1
  • Dagger2 入門 2016-12-21 更新:添加@Subcomponent注解以及Lazy與Provider...
    fxzou閱讀 28,558評(píng)論 77 331
  • 寫在前面:我目前就職于阿里巴巴-菜鳥肪跋,團(tuán)隊(duì)目前缺人歧蒋,招聘java和客戶端開發(fā),招聘對(duì)象為:社招和19屆畢業(yè)的校招生...
    littleKang閱讀 115,410評(píng)論 93 745