架構(gòu)進(jìn)階帜篇,Dagger2的原理及使用詳解

目錄

  • 一:Dagger2是什么惯雳?
  • 二:為什么要有Dagger2
  • 三:Dagger2如何使用
  1. 基本的概念
  2. 如何使用Dagger2
  3. 高級(jí)用法
  • (1)構(gòu)造方法需要其他參數(shù)時(shí)候
  • (2) 模塊之間的依賴關(guān)系
  • (3) @Named注解使用
  • (4) @Singleton注解
  • (5)自定義Scoped
  • (6)Subcomponent
  • (7)lazy 和 Provider
  • 四: MVP + Dagger2

Ps:文末有架構(gòu)師進(jìn)階資料和面試題資料


一:Dagger2是什么队橙?

是一個(gè)依賴注入框架拦坠,butterknife也是一個(gè)依賴注入框架连躏。不過(guò)butterknife,最多叫奶油刀贞滨,Dagger2被叫做利器啊入热,他的主要作用,就是對(duì)象的管理晓铆,其目的是為了降低程序耦合勺良。

二:為什么要有Dagger2

8年Android開發(fā)程序員:架構(gòu)進(jìn)階,Dagger2的原理及使用詳解

下面我就手寫了

public class A {
 public void eat() {
 System.out.print("吃飯了");
 }
}

使用的時(shí)候我們就要

A a = new A();
a.eat();

如果現(xiàn)在改了,早A的構(gòu)造方法中必須傳入B對(duì)象

public class A {
 private B b;
 public A(B b) {
 this.b = b;
 }
 public void eat() {
 System.out.print("吃飯了");
 }
}

那么使用的時(shí)候

A a = new A(new B());
a.eat();

可能就有人說(shuō)了骄噪,不就加一個(gè)對(duì)象么尚困,這里只是我舉的一個(gè)很簡(jiǎn)單的例子,看的感覺很簡(jiǎn)單链蕊,但是在實(shí)際開發(fā)中尾组,如果現(xiàn)在改了一個(gè)這個(gè)構(gòu)造方法忙芒。是不是意味著,整個(gè)項(xiàng)目中的都的改讳侨,一不小心, 就是BUG 啊

三:Dagger2如何使用

1. 基本的概念

上來(lái)給你說(shuō)奏属,怎么玩跨跨,肯定懵逼,這里我簡(jiǎn)單說(shuō)一下幾個(gè)概念囱皿,想有個(gè)認(rèn)知勇婴,在往下看,會(huì)好很多嘱腥,Dagger 是通過(guò)@Inject使用具體的某個(gè)對(duì)象耕渴,這個(gè)對(duì)象呢,是由@Provides注解提供齿兔,但是呢橱脸,這個(gè)@Provides只能在固定的模塊中,也就是@Module注解分苇,我們查找的時(shí)候添诉,不是直接去找模塊,而是去找@Component

8年Android開發(fā)程序員:架構(gòu)進(jìn)階医寿,Dagger2的原理及使用詳解

我們反向推導(dǎo)栏赴,當(dāng)我們使用

@Inject
A a

想要獲取a對(duì)象的示例的時(shí)候,Dagger2 會(huì)先去找靖秩,當(dāng)前Activity或者Fragment所連接的橋梁须眷,例如上圖中,連接的只有一個(gè)橋梁沟突,實(shí)際上可以有多個(gè)花颗,這個(gè)橋梁,會(huì)去尋找他所依賴的模塊事扭,如圖中捎稚,依賴了模塊A,和模塊B求橄,然后在模塊中今野,會(huì)去尋找@Providers注解,去尋找A的實(shí)例化對(duì)象罐农。

2. 如何使用Dagger2

(1) 引入依賴庫(kù)

Dagger2官網(wǎng)

compile 'com.google.dagger:dagger:2.11'
 annotationProcessor 'com.google.dagger:dagger-compiler:2.11'

(2) 創(chuàng)建Moudule

//第一步 添加@Module 注解
@Module
public class MainModule {
}

(3)創(chuàng)建具體的示例

//第一步 添加@Module 注解
@Module
public class MainModule {
 //第二步 使用Provider 注解 實(shí)例化對(duì)象
 @Provides
 A providerA() {
 return new A();
 }
}

(4)創(chuàng)建一個(gè)Component

//第一步 添加@Component
//第二步 添加module
@Component(modules = {MainModule.class})
public interface MainComponent {
 //第三步 寫一個(gè)方法 綁定Activity /Fragment
 void inject(MainActivity activity);
}

(5)Rebuild Project

8年Android開發(fā)程序員:架構(gòu)進(jìn)階条霜,Dagger2的原理及使用詳解

然后AS 會(huì)自動(dòng)幫我們生成一個(gè)

8年Android開發(fā)程序員:架構(gòu)進(jìn)階,Dagger2的原理及使用詳解

開頭都是以Dagger開始的

(6)將Component與Activity/Fragment綁定關(guān)系

package com.allens.daggerdemo;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import com.allens.daggerdemo.Bean.A;
import com.allens.daggerdemo.component.DaggerMainConponent;
import javax.inject.Inject;

public class MainActivity extends AppCompatActivity {
 /***
 * 第二步 使用Inject 注解涵亏,獲取到A 對(duì)象的實(shí)例
 */
 @Inject
 A a;

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

 /***
 * 第一步 添加依賴關(guān)系
 */
 //第一種方式
 DaggerMainConponent.create().inject(this);

 //第二種方式
 DaggerMainConponent.builder().build().inject(this);

 /***
 * 第三步 調(diào)用A 對(duì)象的方法
 */
 a.eat();
 }
}

肯定有小伙伴說(shuō)了宰睡,為了拿到一個(gè)對(duì)象蒲凶,這么大個(gè)彎,太麻煩了拆内。別急慢慢看旋圆,路要一步一步走嘛

3. 高級(jí)用法

(1)構(gòu)造方法需要其他參數(shù)時(shí)候

怎么說(shuō)呢,就和最來(lái)時(shí)的意思一樣麸恍,

A a = new A(new B());
a.eat();

這種情況灵巧,如何使用Dagger2呢

肯定有小伙伴這么想

@Provides
 A providerA() {
 return new A(new B());
 }

直接 new 一個(gè)B ,這樣的使用方法抹沪,是不對(duì)的?桃蕖!H谂贰C羝!噪馏!麦到,不對(duì)的!J判健S缫!6谩2角濉!虏肾,不對(duì)的@ !7夂馈G绰帧!4挡骸5诓健!缘琅!

正確的打開方式

這時(shí)候粘都,我們什么都不用該,只需要在moudule中添加一個(gè)依賴就可以了

@Module
public class MainModule {

 /***
 * 構(gòu)造方法需要其他參數(shù)時(shí)候
 *
 * @return
 */
 @Provides
 B providerB() {
 return new B();
 }

 @Provides
 A providerA(B b) {
 return new A(b);
 }
}

(2) 模塊之間的依賴關(guān)系

模塊與模塊之間的聯(lián)系刷袍,

@Module (includes = {BModule.class})// includes 引入)
public class AModule {
 @Provides
 A providerA() {
 return new A();
 }
}

這樣的話翩隧,Dagger會(huì)現(xiàn)在A moudule 中尋找對(duì)象,如果沒找到呻纹,會(huì)去找module B 中是否有被Inject注解的對(duì)象堆生,如果還是沒有专缠,那么GG,拋出異常

一個(gè)Component 應(yīng)用多個(gè) module

@Component(modules = {AModule.class,BModule.class})
public interface MainComponent {
 void inject(MainActivity activity);
}

dependencies 依賴其他Component

@Component(modules = {MainModule.class}, dependencies = AppConponent.class)
public interface MainConponent {
 void inject(MainActivity activity);
}

注意 這里有坑淑仆。一下會(huì)講解


(3) @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");
 }

}

在Activity/Fragment中使用

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);
 }

}

打印Log

07-14 01:46:01.170 2006-2006/? I/TAG: apiDev--->com.allen.rxjava.MainApi@477928f
07-14 01:46:01.170 2006-2006/? I/TAG: apiRelease--->com.allen.rxjava.MainApi@f2b291c

(4) @Singleton注解

單利模式糯景,是不是超級(jí)方便嘁圈,你想然哪個(gè)對(duì)象單利化,直接在他的Provider上添加@Singleton 就行了

例如

@Singleton
 @Provides
 A providerA(B b) {
 return new A(b);
 }

注意: 第一個(gè)坑s盎础!钞澳!

如果 moudule所依賴的Comonent 中有被單利的對(duì)象怠惶,那么Conponnent也必須是單利的

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

然后 在Activity中使用,直接打印a1 a2 的地址轧粟,

@Inject
 A a2;
 @Inject
 A a1;

可以看到Log

12-30 01:32:58.420 3987-3987/com.allens.daggerdemo E/TAG: A1---->com.allens.daggerdemo.Bean.A@11fa1ba
12-30 01:32:58.420 3987-3987/com.allens.daggerdemo E/TAG: A1---->com.allens.daggerdemo.Bean.A@11fa1ba

不相信的小伙伴可以吧@Singleton去掉試試

現(xiàn)在我們完成了單利策治,然后做了一個(gè)事情,就是點(diǎn)擊某個(gè)按鈕兰吟,跳轉(zhuǎn)到一個(gè)新的Activiry,兩邊都引用同樣一個(gè)A 對(duì)象通惫,打印A 的地址,

說(shuō)一下混蔼,一個(gè)Conponent 可以被對(duì)個(gè)Activity/Fragment 引用,如

@Singleton
@Component(modules = {MainModule.class})
public interface MainConponent {
 void inject(MainActivity activity);
 void inject(TestAct activity);
}

上面與兩個(gè)Activity, MainActivity 和 TestAct 履腋,都引用相同的 對(duì)象,答應(yīng)地址看看

12-30 00:48:17.477 2788-2788/com.allens.daggerdemo E/TAG: A1---->com.allens.daggerdemo.Bean.A@11fa1ba
12-30 00:48:17.517 2788-2788/com.allens.daggerdemo E/TAG: A2---->com.allens.daggerdemo.Bean.A@4f81861

竟然不同惭嚣,說(shuō)好的單利呢

注意: 第二個(gè)坑遵湖,單利對(duì)象只能在同一個(gè)Activity中有效。不同的Activity 持有的對(duì)象不同

那有人就要問(wèn)了晚吞,沒什么辦法么延旧,我就想全局只要一個(gè)實(shí)例化對(duì)象啊槽地? 辦法肯定是有的迁沫,


(5) 自定義Scoped

/**
 * @作者 : Android架構(gòu)
 * @創(chuàng)建日期 :2017/7/14 下午3:04
 * @方法作用:
 * 參考Singleton 的寫法
 * Scope 標(biāo)注是Scope
 * Documented 標(biāo)記在文檔
 * @Retention(RUNTIME) 運(yùn)行時(shí)級(jí)別
 */
@Scope
@Documented
@Retention(RUNTIME)
public @interface ActivityScoped {
}

首先想一下,什么樣的對(duì)象捌蚊,能夠做到全局單例集畅,生命周期肯定和APP 綁定嘛,這里我做演示逢勾,一個(gè)AppAip 我們要對(duì)這個(gè)對(duì)象牡整,全局單利,所以二話不說(shuō)溺拱,先給Application 來(lái)個(gè)全家桶逃贝,

Module

@Module
public class AppModule {

 @Singleton
 @Provides
 AppApi providerAppApi() {
 return new AppApi();
 }
}

Component

@Singleton
@Component(modules = AppModule.class)
public interface AppComponent {
 AppApi getAppApi();
}

Application

public class MyApp extends Application {

 private AppConponent appComponent;

 @Override
 public void onCreate() {
 super.onCreate();
 appComponent = DaggerAppConpoment.create();
 }

 public AppConponent getAppComponent() {
 return appConponent;
 }
}

最后是如何使用

首先谣辞,這個(gè)是個(gè)橋梁,依賴方式沐扳,上文已經(jīng)說(shuō)過(guò)了

@ActivityScoped
@Component(modules = {MainModule.class}, dependencies = AppConponent.class)
public interface MainComponent {
 void inject(MainActivity activity);
 void inject(TestAct activity);
}

細(xì)心的小伙伴可能已經(jīng)發(fā)現(xiàn)了泥从,只有在上面一個(gè)MainComponent添加了一個(gè)@ActivityScoped,這里說(shuō)明一下,@Singleton是Application 的單利

注意沪摄,第三個(gè)坑躯嫉,子類component 依賴父類的component ,子類component的Scoped 要小于父類的Scoped杨拐,Singleton的級(jí)別是Application

所以祈餐,我們這里的@Singleton 級(jí)別大于我們自定義的@ActivityScoped,同時(shí)哄陶,對(duì)應(yīng)module 所依賴的component 帆阳,也要放上相應(yīng)的Scope

好吧,上面的例子屋吨,打印Log.

12-30 02:16:30.899 4717-4717/? E/TAG: A1---->com.allens.daggerdemo.Bean.AppApi@70bfc2
12-30 02:16:31.009 4717-4717/? E/TAG: A2---->com.allens.daggerdemo.Bean.AppApi@70bfc2

一樣啦

爬坑指南(極度重要)

  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

(6)Subcomponent

這個(gè)是系統(tǒng)提供的一個(gè)Component,當(dāng)使用Subcomponent,那么默認(rèn)會(huì)依賴Component

例如

@Subcomponent(modules = TestSubModule.class)
public interface TestSubComponent {
 void inject(MainActivity activity);
}
@Component(modules = {MainModule.class})
public interface MainConponent {
 TestSubComponent add(TestSubModule module);
}

在TestSubComponent中 我void inject(MainActivity activity);敢课,便是這個(gè)橋梁阶祭,我是要注入到MainActivity,但是dagger 并不會(huì)給我生成一個(gè)Dagger開頭的DaggerTestSubComponent 這個(gè)類,如果我想使用TestSubModule.class里面提供的對(duì)象翎猛,依然還是使用DaggerMainConponent例如

DaggerMainConponent
 .builder()
 .mainModule(new MainModule())
 .build()
 .add(new TestSubModule())
 .inject(this);

可以看到這里有一個(gè)add的方法胖翰,真是我在MainConponent添加的TestSubComponent add(TestSubModule module);


(7)lazy 和 Provider

public class Main3Activity extends AppCompatActivity {

 @PresentForContext
 @Inject
 Lazy<Present> lazy;
 @PresentForName
 @Inject
 Provider<Present> provider;
 @Override
 protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 setContentView(R.layout.activity_main3);

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

 activityComponent.injectActivity(this);
 Present present = lazy.get();
 Present present1 = provider.get();
 }
}

其中Lazy(懶加載)的作用好比component初始化了一個(gè)present對(duì)象,然后放到一個(gè)池子里,需要的時(shí)候就get它,所以你每次get的時(shí)候拿到的對(duì)象都是同一個(gè);并且當(dāng)你第一次去get時(shí),它才會(huì)去初始化這個(gè)實(shí)例.

procider(強(qiáng)制加載)的作用:

1:同上當(dāng)你第一次去get時(shí),它才會(huì)去初始化這個(gè)實(shí)例

2:后面當(dāng)你去get這個(gè)實(shí)例時(shí),是否為同一個(gè),取決于他Module里實(shí)現(xiàn)的方式


四: MVP + Dagger2

這是現(xiàn)在主流的設(shè)計(jì)架構(gòu)

MVP,這個(gè)我會(huì)在后面的文章介紹切厘,這里不做太多解釋

當(dāng)你了解MVP 的時(shí)候萨咳,你就知道,所有的業(yè)務(wù)邏輯全在Presenter疫稿,

換句話培他, presenter 持有的對(duì)象,控制著你程序的全部邏輯遗座,這在dagger 中舀凛,講白了 我們只要將所有的presetner 對(duì)象控制就可以了

下面附上目錄結(jié)構(gòu),當(dāng)然僅僅作為參考途蒋。dagger 強(qiáng)大的用法還是需要各位自己去體會(huì)猛遍,下面的項(xiàng)目 是我剛剛學(xué)會(huì)dagger 時(shí)候 寫的一個(gè)項(xiàng)目

8年Android開發(fā)程序員:架構(gòu)進(jìn)階,Dagger2的原理及使用詳解
8年Android開發(fā)程序員:架構(gòu)進(jìn)階,Dagger2的原理及使用詳解

可以看到 懊烤,我是 將所有的activity 或者 fragment 全部添加在同一個(gè)Component中梯醒,當(dāng)然現(xiàn)在的話 不推薦,比如Utils 你可以專門做一個(gè)Component腌紧,

首先放上我的Module茸习,公司項(xiàng)目,很多東西沒敢放上來(lái)壁肋,體諒号胚,可以看到 我這里提供了一個(gè)SplashPresenter,也就是啟動(dòng)頁(yè)的Presneter,業(yè)務(wù)邏輯

@Module
public class ApiModule {

 public ApiModule() {

 }

 @Provides
 @Singleton
 Handler provideHandler() {
 return new Handler();
 }

 @Provides
 @Singleton
 SQLiteDatabase provideSQLiteDatabase() {
 return new DataBaseHelper(MyApp.context, Config.SqlName, null, Config.SqlVersion).getWritableDatabase();
 }

 /**
 * @ User : Android架構(gòu)
 * @ 創(chuàng)建日期 : 2017/7/13 下午3:24
 * @模塊作用 :
 * <p>
 * ====================================================================================================================================
 * ====================================================================================================================================
 */
 private SplashPresenter splashPresenter;

 public ApiModule(SplashAct splashAct) {
 splashPresenter = new SplashPresenter(splashAct, new SplashModel());
 }

 @Provides
 @Singleton
 SplashPresenter provideSplashPresenter() {
 return splashPresenter;
 }

 .....
}

當(dāng)我使用的時(shí)候浸遗,只需要注入即可猫胁,如下代碼

public class SplashAct extends BaseActivity implements SplashContract.View {

 @Inject
 SplashPresenter presenter;

 @Inject
 Handler handler;

 @Inject
 ApiService apiService;

 @Override
 protected void onCreate() {
 setContentView(R.layout.activity_splash);
 }

 @Override
 protected void initInject() {
 DaggerApiComponent.builder()
 .apiModule(new ApiModule(this))
 .build()
 .inject(this);
 }

 @Override
 protected void initListener() {
 presenter.getWordsInfo(true, apiService);
 }

 @Override
 public void gotoLogInAct() {
 handler.postDelayed(new Runnable() {
 @Override
 public void run() {
 startActivity(new Intent(SplashAct.this, LogInAct.class));
 finish();
 }
 }, 1500);
 }
}

最后

給大家分享一份移動(dòng)架構(gòu)大綱,包含了移動(dòng)架構(gòu)師需要掌握的所有的技術(shù)體系跛锌,大家可以對(duì)比一下自己不足或者欠缺的地方有方向的去學(xué)習(xí)提升杜漠;

需要高清架構(gòu)圖以及圖中視頻資料和文章項(xiàng)目源碼的可以加入我的技術(shù)交流群:825106898私聊群主小姐姐免費(fèi)獲取

image
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市察净,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌盼樟,老刑警劉巖氢卡,帶你破解...
    沈念sama閱讀 206,214評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異晨缴,居然都是意外死亡译秦,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,307評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門击碗,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)筑悴,“玉大人,你說(shuō)我怎么就攤上這事稍途「罅撸” “怎么了?”我有些...
    開封第一講書人閱讀 152,543評(píng)論 0 341
  • 文/不壞的土叔 我叫張陵械拍,是天一觀的道長(zhǎng)突勇。 經(jīng)常有香客問(wèn)我,道長(zhǎng)坷虑,這世上最難降的妖魔是什么甲馋? 我笑而不...
    開封第一講書人閱讀 55,221評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮迄损,結(jié)果婚禮上定躏,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好痊远,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,224評(píng)論 5 371
  • 文/花漫 我一把揭開白布垮抗。 她就那樣靜靜地躺著,像睡著了一般拗引。 火紅的嫁衣襯著肌膚如雪借宵。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,007評(píng)論 1 284
  • 那天矾削,我揣著相機(jī)與錄音壤玫,去河邊找鬼。 笑死哼凯,一個(gè)胖子當(dāng)著我的面吹牛欲间,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播断部,決...
    沈念sama閱讀 38,313評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼猎贴,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了蝴光?” 一聲冷哼從身側(cè)響起她渴,我...
    開封第一講書人閱讀 36,956評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎蔑祟,沒想到半個(gè)月后趁耗,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,441評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡疆虚,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,925評(píng)論 2 323
  • 正文 我和宋清朗相戀三年苛败,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片径簿。...
    茶點(diǎn)故事閱讀 38,018評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡罢屈,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出篇亭,到底是詐尸還是另有隱情缠捌,我是刑警寧澤,帶...
    沈念sama閱讀 33,685評(píng)論 4 322
  • 正文 年R本政府宣布暗赶,位于F島的核電站鄙币,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏蹂随。R本人自食惡果不足惜十嘿,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,234評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望岳锁。 院中可真熱鬧绩衷,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,240評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)上遥。三九已至科展,卻和暖如春算谈,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背曹货。 一陣腳步聲響...
    開封第一講書人閱讀 31,464評(píng)論 1 261
  • 我被黑心中介騙來(lái)泰國(guó)打工咆繁, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人顶籽。 一個(gè)月前我還...
    沈念sama閱讀 45,467評(píng)論 2 352
  • 正文 我出身青樓玩般,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親礼饱。 傳聞我的和親對(duì)象是個(gè)殘疾皇子坏为,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,762評(píng)論 2 345

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