6.絕絕子--Android - 抖音使用Dagger2實(shí)現(xiàn)MVP+RecycleView解藕 ( 依賴注入一看就明白) 沒(méi)看過(guò)你就Out了

dagger的用途就是:讓你不需要初始化對(duì)象苹粟。換句話說(shuō)肿嘲,任何對(duì)象聲明完了就能直接用滑燃。

依賴注入的好處

重用 Car,依賴通過(guò)外部傳入過(guò)來(lái)疆液!

`* 重用類以及分離依賴項(xiàng):更容易換掉依賴項(xiàng)的實(shí)現(xiàn)一铅。由于控制反轉(zhuǎn),代碼重用得以改進(jìn)堕油,并且類不再控制其依賴項(xiàng)的創(chuàng)建方式馅闽,而是支持任何配置飘蚯。

  • 易于重構(gòu):依賴項(xiàng)成為 API Surface 的可驗(yàn)證部分,因此可以在創(chuàng)建對(duì)象時(shí)或編譯時(shí)進(jìn)行檢查福也,而不是作為實(shí)現(xiàn)詳情隱藏局骤。`

目的,改造演變:

第一種:直接new 暴凑,很多個(gè)地方new

第二種:統(tǒng)一new 峦甩,通過(guò)工廠的方式new,以后只改一個(gè)地方就可以

第三種:統(tǒng)一的地方现喳,自動(dòng)new

如何解藕凯傲?

1.MVP + Dagger2

專為MVP模式中的P層和V層做進(jìn)一步解耦

因?yàn)樵贛VP模式中Activity持有presenter的引用,同時(shí)presenter也持有view的引用嗦篱,這樣便于更新UI界面冰单,這樣Activity就和 presenter僅僅的耦合在一起了,而Dagger2是依賴注入框架就是解耦合的灸促,所以子MVP中使用Dagger2也就再好不過(guò)了诫欠。

activity持有了presenter的引用并且創(chuàng)建了該對(duì)象,但是如果presenter的構(gòu)造函數(shù)發(fā)生改變則這里也需要改變浴栽,其實(shí)所有和presenter構(gòu)造函數(shù)相關(guān)的代碼都要改變荒叼。 

把很多對(duì)象new的地方統(tǒng)一起來(lái)了。之前用的是工廠模式的方式典鸡!工廠比直接new好一點(diǎn),dagger2是自動(dòng)注冊(cè)被廓,自動(dòng)手寫了很多new

我的理解:

1).MVP中 present還是會(huì)有view的依賴!

                如果很多個(gè)地方使用這個(gè)presenter萝玷。只要改一個(gè)地方就可以了嫁乘,不用改多個(gè)地方。

2). 另外一種情況:

     A里面有B球碉, B里面有c亦渗,C里面有D。

如果都手動(dòng)new 汁尺,如果后面改起來(lái)法精,就會(huì)很麻煩!

2.dagger2+組件化


一:Dagger2是什么痴突?

是一個(gè)依賴注入框架搂蜓,butterknife也是一個(gè)依賴注入框架。不過(guò)butterknife辽装,最多叫奶油刀帮碰,Dagger2被叫做利器啊,他的主要作用拾积,就是對(duì)象的管理

優(yōu)點(diǎn):

其目的是為了降低程序耦合殉挽。

隨即而來(lái)的就是可測(cè)試性丰涉,可維護(hù),可擴(kuò)展性就大大提高了

很多小白對(duì)于Dagger2是啥渾然不知斯碌,更不知其能帶來(lái)的好處了一死。

這里舉個(gè)例子,比如有個(gè)類A傻唾,他的構(gòu)造函數(shù)需要傳入B,C投慈;然后代碼里有10個(gè)地方實(shí)例化了A,那如果功能更改冠骄,A的構(gòu)造函數(shù)改成了只有B伪煤,這個(gè)時(shí)候,你是不是要去這10個(gè)地方一個(gè)一個(gè)的改凛辣?如果是100個(gè)地方抱既,你是不是要吐血?扁誓!如果采用dagger2防泵,這樣的需求只需要改1-2個(gè)地方,你感覺(jué)怎么樣跋理?對(duì)你有誘惑嗎?

原理:

這類依賴注入框架都已經(jīng)采用了apt代碼自動(dòng)生成技術(shù)恬总,其注解是停留在編譯時(shí)前普,完全不影響性能。

dagger是使用依賴注入的方式壹堰,使用Annotation給需要注入的對(duì)象做標(biāo)記拭卿,通過(guò)inject()方法自動(dòng)注入所有對(duì)象,從而完成自動(dòng)的初始化

dagger2 解決什么問(wèn)題

第一:dagger 是一個(gè)依賴注入框架贱纠,首要任務(wù)當(dāng)然是解決依賴注入的問(wèn)題峻厚。
第二:dagger主要想通過(guò)編譯時(shí)產(chǎn)生代碼的方式來(lái)解決那些基于反射的依賴注入框架所存在的缺點(diǎn),例如性能問(wèn)題谆焊,開(kāi)發(fā)過(guò)程中存在的問(wèn)題惠桃。

注入的形式:

<pre style="margin: 8px 0px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-thickness: initial; text-decoration-style: initial; text-decoration-color: initial; background-color: rgb(43, 43, 43); color: rgb(169, 183, 198); font-family: 宋體; font-size: 0.8rem;">public class MainActivity extends AppCompatActivity {

@Named("dev")
@Inject
MainApi apiDev;    @Named("release")
@Inject
MainApi apiRelease;    @Override

protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); DaggerMainComponent.builder()
.mainModule(new MainModule(this))
.mainChildModule(new MainChildModule())
.build()
.inject(this);
apiDev.eat();
apiRelease.eat();
Log.i("TAG","apiDev--->" + apiDev);
Log.i("TAG","apiRelease--->" + apiRelease);
}</pre>

3要素:Inject Component Module

@Inject

在A類中標(biāo)記B類的字段:告訴dagger 我們要注入B類的實(shí)例到A類中,你幫我搞定辖试。

在B類中標(biāo)記B類的構(gòu)造函數(shù):告訴dagger B類是一個(gè)可以被注入的類辜王,如果你想把B的實(shí)例對(duì)象注入到其他類中,例如注入到A類中罐孝,是沒(méi)有任何問(wèn)題的呐馆。

@Component :中間橋接,對(duì)外接口

一般是一個(gè)使用 @Component標(biāo)記的接口莲兢,其持有A類的實(shí)例汹来,其在A類中發(fā)現(xiàn)有使用@Inject標(biāo)記的屬性b

@Module和 providers綁定在一起

C類是一個(gè)沒(méi)有使用@Inject注解其構(gòu)造函數(shù)的類

@Module注解表示续膳,這個(gè)類是一個(gè)Module,Module的作用是提供信息收班,讓ObjectGraph知道應(yīng)該怎樣注入所有的依賴

3坟岔、Component依賴Component

1、最簡(jiǎn)單不帶ModuleInject方式

由我們自己定義的類闺阱,我們可以自由修改的情況下我們使用這種方式炮车,也分為兩種:帶參數(shù)和不帶參數(shù)的。

a酣溃、構(gòu)造參數(shù)不帶參數(shù)的:

例子:

b瘦穆、構(gòu)造參數(shù)帶參數(shù)的:

構(gòu)造函數(shù)如果帶了inject注入的話,類就默認(rèn)被注入了赊豌,不用像無(wú)慘的一樣

例子:

發(fā)現(xiàn)Factory的構(gòu)造函數(shù)被@Inject標(biāo)注了且?guī)в幸粋€(gè)參數(shù)扛或,

然后dagger2就去尋找Product發(fā)現(xiàn)它的構(gòu)造函數(shù)也被@Inject標(biāo)注并且無(wú)參數(shù),于是dagger2把Product的實(shí)例注入給FactoryActivity

2碘饼、帶ModuleInject方式

應(yīng)用場(chǎng)景:若是我們引入的第三方庫(kù)不能隨意改動(dòng)代碼的話就不方便了熙兔,我們這里使用如下RetrofitManager模擬不可改動(dòng)代碼的情況:

  • 第三方庫(kù)提供的類,它們的構(gòu)造方法不能被注解

對(duì)于這樣的情況艾恼,可以使用@Provides注解來(lái)提供專用的初始化方法住涉,實(shí)現(xiàn)自定義依賴。

@Provides
Coder provideCoder(Boss boss) {
    return new Coder(boss);
}

include的用法

<pre style="margin: 8px 0px; background-color: rgb(43, 43, 43); color: rgb(169, 183, 198); font-family: 宋體; font-size: 0.8rem;">@Module (includes = {BModule.class})// includes 引入) public class AModule {
@Provides
A providerA() {
return new A();
}
}</pre>

@Named注解用

相當(dāng)于有個(gè)表示钠绍,雖然大家都是同一個(gè)對(duì)象舆声,但是實(shí)例化對(duì)象不同就不如

 A a1 = new A();    A a2 = new A();// a1  a2 能一樣嘛

Module中 使用@Named注解

@Module
public class MainModule {

    private MainActivity activity;

    public MainModule(MainActivity activity) {
        this.activity = activity;
    }

    @Named("dev")
    @Provides
    MainApi provideMainApiDev(MainChildApi mainChildApi, String url) {
        return new MainApi(mainChildApi, activity,"dev");
    }

    @Named("release")
    @Provides
    MainApi provideMainApiRelease(MainChildApi mainChildApi, String url) {
        return new MainApi(mainChildApi, activity,"release");
    }

}來(lái)源: http://www.reibang.com/p/2cd491f0da01

在Activity/Fragment中使用

<pre class="hljs java" style="margin: 8px 0px;">

<pre style="margin: 8px 0px; background-color: rgb(43, 43, 43); color: rgb(169, 183, 198); font-family: 宋體; font-size: 0.8rem;">public class MainActivity extends AppCompatActivity {

@Named("dev")
@Inject
MainApi apiDev;    @Named("release")
@Inject
MainApi apiRelease;    @Override

protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); DaggerMainComponent.builder()
.mainModule(new MainModule(this))
.mainChildModule(new MainChildModule())
.build()
.inject(this);
apiDev.eat();
apiRelease.eat();
Log.i("TAG","apiDev--->" + apiDev);
Log.i("TAG","apiRelease--->" + apiRelease);
}

}</pre>

</pre>

<pre class="hljs java" style="margin: 8px 0px;">在項(xiàng)目中的應(yīng)用場(chǎng)景和實(shí)例:
</pre>

<pre class="hljs java" style="margin: 8px 0px;">https://blog.csdn.net/soslinken/article/details/52184113</pre>

注意:

實(shí)質(zhì)上,Dagger會(huì)在編譯時(shí)對(duì)代碼進(jìn)行檢查柳爽,并在檢查不通過(guò)的時(shí)候報(bào)編譯錯(cuò)誤(為什么媳握?這和Dagger的原理有關(guān),有興趣的話可以關(guān)注我之后發(fā)布的Dagger詳解)磷脯。檢查內(nèi)容主要有三點(diǎn):

  1. 所有含有依賴注入的類蛾找,需要被顯式 聲明在相應(yīng)的Module中。
  2. 一個(gè)Module中所有@Provides方法的參數(shù)都必須在這個(gè)Module種提供相應(yīng)的@Provides方法赵誓,或者在@Module注解后添加“complete = false”注明這是一個(gè)不完整Module(即它會(huì)被其他Module所擴(kuò)展)打毛。
  3. 一個(gè)Module中所有的@Provides方法都要被它聲明的注入對(duì)象所使用,或者在@Module注解后添加“l(fā)ibrary = ture”注明(即它是為了擴(kuò)展其他Module而存在的)俩功。

@Binds:的使用隘冲。

————————————————

總結(jié):

1.作用域--------重點(diǎn),比較難的地方绑雄!

2.組件依賴

3.子組件 subConponent

爬坑指南(極度重要)

  1. Provide 如果是單例模式 對(duì)應(yīng)的Compnent 也要是單例模式
  2. inject(Activity act) 不能放父類
  3. 即使使用了單利模式展辞,在不同的Activity 對(duì)象還是不一樣的
  4. 依賴component, component之間的Scoped 不能相同
  5. 子類component 依賴父類的component 万牺,子類component的Scoped 要小于父類的Scoped罗珍,Singleton的級(jí)別是Application
  6. 多個(gè)Moudle 之間不能提供相同的對(duì)象實(shí)例
  7. Moudle 中使用了自定義的Scoped 那么對(duì)應(yīng)的Compnent 使用同樣的Scoped

重點(diǎn)是:處理作用域provider

通過(guò)APT+javapoAT在編譯時(shí)候生成上面3個(gè)類洽腺!

APT的process()方法是什么時(shí)候執(zhí)行?

原理分析:

1.a是怎么實(shí)例化的

2.b和c是怎么是咧化的

3.他們是怎么綁定的

原理:在build里面生成了很多的類覆旱,工廠模式蘸朋,代理模式,A_Factory ,proxyProviderC

單列如何實(shí)現(xiàn)?

保持conponent是全局唯一的扣唱,通過(guò)application中初始化藕坯!

Dragger的原理:

[圖片上傳失敗...(image-115c54-1640679669730)]

1.DaggerPengConponnet------注入和對(duì)象的關(guān)系

在里面,通過(guò)工廠模式得到provider

就是下面要用的2個(gè)類PengModule_GetHttpObjectFactory和MainActivity_MembersInjector

<pre style="margin: 8px 0px; background-color: rgb(43, 43, 43); color: rgb(169, 183, 198); font-family: "JetBrains Mono", monospace; font-size: 0.817rem;">public final class DaggerPengConponnet implements PengConponnet {
private Provider<HttpObject> getHttpObjectProvider; private MembersInjector<MainActivity> mainActivityMembersInjector; private DaggerPengConponnet(Builder builder) {
assert builder != null;
initialize(builder);
}

public static Builder builder() {
return new Builder();
}

public static PengConponnet create() {
return new Builder().build();
}

@SuppressWarnings("unchecked")
private void initialize(final Builder builder) {

this.getHttpObjectProvider = PengModule_GetHttpObjectFactory.create(builder.pengModule);   this.mainActivityMembersInjector = MainActivity_MembersInjector.create(getHttpObjectProvider);

}

@Override
public void injectActivity(MainActivity mainActivity) {
mainActivityMembersInjector.injectMembers(mainActivity);
}

public static final class Builder {
private PengModule pengModule; private Builder() {}

public PengConponnet build() {
  if (pengModule == null) {
    this.pengModule = new PengModule();

}
return new DaggerPengConponnet(this);
}

public Builder pengModule(PengModule pengModule) {
  this.pengModule = Preconditions.checkNotNull(pengModule);

return this; }
}
}
</pre>

2.PengModule_GetHttpObjectFactory --------工廠噪沙,new出對(duì)象炼彪。

通過(guò)工廠模式創(chuàng)建對(duì)象

<pre style="margin: 8px 0px; background-color: rgb(43, 43, 43); color: rgb(169, 183, 198); font-family: "JetBrains Mono", monospace; font-size: 0.817rem;">public final class PengModule_GetHttpObjectFactory implements Factory<HttpObject> {
private final PengModule module; public PengModule_GetHttpObjectFactory(PengModule module) {
assert module != null;
this.module = module;
}

@Override
public HttpObject get() {
return Preconditions.checkNotNull(
module.getHttpObject(), "Cannot return null from a non-@Nullable @Provides method");
}

public static Factory<HttpObject> create(PengModule module) {
return new PengModule_GetHttpObjectFactory(module);
}
}3.MainActivity_MembersInjector -----賦值</pre>

通過(guò)provider得到了需要注入的對(duì)象

3.MainActivity_MembersInjector:注入綁定

<pre style="margin: 8px 0px; background-color: rgb(43, 43, 43); color: rgb(169, 183, 198); font-family: "JetBrains Mono", monospace; font-size: 0.817rem;">public final class MainActivity_MembersInjector implements MembersInjector<MainActivity> {
private final Provider<HttpObject> httpObjectProvider; public MainActivity_MembersInjector(Provider<HttpObject> httpObjectProvider) {
assert httpObjectProvider != null;
this.httpObjectProvider = httpObjectProvider;
}

public static MembersInjector<MainActivity> create(Provider<HttpObject> httpObjectProvider) {
return new MainActivity_MembersInjector(httpObjectProvider);
}

@Override
public void injectMembers(MainActivity instance) {
if (instance == null) {
throw new NullPointerException("Cannot inject members into a null reference");
}
instance.httpObject = httpObjectProvider.get();
}

public static void injectHttpObject(
MainActivity instance, Provider<HttpObject> httpObjectProvider) {
instance.httpObject = httpObjectProvider.get();
}
}</pre>

20211227最新使用:

[圖片上傳失敗...(image-cef848-1640679669730)]

使用4部曲

現(xiàn)在用Dagger2來(lái)改造,總體來(lái)說(shuō)就是4步:

  • 1 在Adapter構(gòu)造器中加入@Inject注解(告訴他正歼,如何創(chuàng)建對(duì)象)
  • 2 構(gòu)建 Module(不一定需要)
  • 3 構(gòu)建 Component(聲明是dagger的組件辐马,傳入的參數(shù)是注入到哪里去)
  • 4 完成依賴注入(調(diào)用完成注入)

在操作中會(huì)使用到了@Inject、@Module局义、@Provides喜爷、@Conponent注解,那么他們分別在完成什么工作萄唇?

MainActivityPresenter presenter = new MainActivityPresenter(this);

@Inject @Conponent @Module @Provides

這四個(gè)注解可以這么理解檩帐,@Inject承擔(dān)了=號(hào)左邊的工作,@Conponent 承擔(dān)了=號(hào)的工作另萤, @Module @Provides承擔(dān)了=號(hào)右邊的工作

自己的步驟理解:

1.本來(lái)就有的bean對(duì)象獲取其他對(duì)象httpObject

2.定義module:用來(lái)裝載上面的object,一個(gè)module可以有多個(gè)object

3.定義組件component: 用來(lái)裝module,一個(gè)component可以有多個(gè)module,一般是一個(gè)module.

4.使用湃密,在activty中,直接定義httpobject,然后oncreate通過(guò)注解注入就可以了仲墨。

具體代碼:

[圖片上傳失敗...(image-8e9472-1640679669730)]

第一步: Bean

<pre style="margin: 8px 0px; background-color: rgb(43, 43, 43); color: rgb(169, 183, 198); font-family: "JetBrains Mono", monospace; font-size: 0.817rem;">public class HttpObject {
}
</pre>

第二步:Module

<pre style="margin: 8px 0px; background-color: rgb(43, 43, 43); color: rgb(169, 183, 198); font-family: "JetBrains Mono", monospace; font-size: 0.817rem;">@Module public class PengModule {

@Provides

public HttpObject getHttpObject() {
return new HttpObject();
}

@Provides

public DatabaseObject getDatabase() {
return new DatabaseObject();
}

}
</pre>

第三步:Componet

<pre style="margin: 8px 0px; background-color: rgb(43, 43, 43); color: rgb(169, 183, 198); font-family: "JetBrains Mono", monospace; font-size: 0.817rem;">@Component(modules = PengModule.class) //可以有多個(gè)module public interface PengConponnet { // 接口給外部調(diào)用
void injectActivity(MainActivity mainActivity); }
</pre>

第四步:使用,需要用自動(dòng)生成的類

<pre style="margin: 8px 0px; background-color: rgb(43, 43, 43); color: rgb(169, 183, 198); font-family: "JetBrains Mono", monospace; font-size: 0.817rem;">public class MainActivity extends AppCompatActivity {

@Inject

HttpObject httpObject; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); //自動(dòng)生成類進(jìn)行注入
DaggerPengConponnet.create().injectActivity(this);
}
}
</pre>

非常不錯(cuò):

http://www.reibang.com/p/2cd491f0da01

?著作權(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)離奇詭異,居然都是意外死亡兜畸,警方通過(guò)查閱死者的電腦和手機(jī)努释,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,970評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)咬摇,“玉大人伐蒂,你說(shuō)我怎么就攤上這事「嘏簦” “怎么了逸邦?”我有些...
    開(kāi)封第一講書(shū)人閱讀 168,983評(píng)論 0 362
  • 文/不壞的土叔 我叫張陵恩沛,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我缕减,道長(zhǎng)雷客,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 59,938評(píng)論 1 299
  • 正文 為了忘掉前任桥狡,我火速辦了婚禮搅裙,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘裹芝。我一直安慰自己部逮,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,955評(píng)論 6 398
  • 文/花漫 我一把揭開(kāi)白布局雄。 她就那樣靜靜地躺著甥啄,像睡著了一般。 火紅的嫁衣襯著肌膚如雪炬搭。 梳的紋絲不亂的頭發(fā)上蜈漓,一...
    開(kāi)封第一講書(shū)人閱讀 52,549評(píng)論 1 312
  • 那天,我揣著相機(jī)與錄音宫盔,去河邊找鬼融虽。 笑死,一個(gè)胖子當(dāng)著我的面吹牛灼芭,可吹牛的內(nèi)容都是我干的有额。 我是一名探鬼主播,決...
    沈念sama閱讀 41,063評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼彼绷,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼巍佑!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起寄悯,我...
    開(kāi)封第一講書(shū)人閱讀 39,991評(píng)論 0 277
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤萤衰,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后猜旬,有當(dāng)?shù)厝嗽跇?shù)林里發(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
  • 文/蒙蒙 一裁僧、第九天 我趴在偏房一處隱蔽的房頂上張望个束。 院中可真熱鬧,春花似錦聊疲、人聲如沸茬底。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,572評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)阱表。三九已至,卻和暖如春贡珊,著一層夾襖步出監(jiān)牢的瞬間最爬,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,671評(píng)論 1 274
  • 我被黑心中介騙來(lái)泰國(guó)打工门岔, 沒(méi)想到剛下飛機(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入門詳解 @(Android) Dagger2入門詳解 參考文章 環(huán)境配置 入門實(shí)例 其他注解和情況...
    JFang閱讀 596評(píng)論 1 0
  • 寫在前面:我目前就職于阿里巴巴-菜鳥(niǎo)互艾,團(tuán)隊(duì)目前缺人,招聘java和客戶端開(kāi)發(fā)讯泣,招聘對(duì)象為:社招和19屆畢業(yè)的校招生...
    littleKang閱讀 115,409評(píng)論 93 745
  • 前言 做這個(gè)項(xiàng)目的初衷是想練手纫普,因?yàn)楝F(xiàn)在rxjava+retrofit框架相當(dāng)火,而公司的同事正在用這個(gè)框架也覺(jué)得...
    xiaoluYi閱讀 2,525評(píng)論 15 12
  • MVP https://juejin.im/post/6844903720036073480#heading-14...
    _Anonymous_閱讀 251評(píng)論 0 0
  • http://zpayh.xyz/2016/07/07/Dagger2%E4%BD%BF%E7%94%A8%E8%...
    奈何心善閱讀 193評(píng)論 0 0