第九章 后臺(tái)默默的勞動(dòng)者核畴,探究服務(wù)

9.1服務(wù)是什么

服務(wù)( Service)是 Android 中實(shí)現(xiàn)程序后臺(tái)運(yùn)行的解決方案膝但,它適合用于去執(zhí)行不需要和用戶交互而且還要求長(zhǎng)期運(yùn)行的任務(wù)。服務(wù)的運(yùn)行不依賴于任何用戶界面谤草,當(dāng)程序被切換到后臺(tái)跟束,服務(wù)仍然能夠保持正常運(yùn)行。但服務(wù)并不是運(yùn)行在一個(gè)獨(dú)立的進(jìn)程當(dāng)中的咖刃,而是依賴于創(chuàng)建服務(wù)時(shí)所在的應(yīng)用程序進(jìn)程泳炉。當(dāng)某個(gè)應(yīng)用程序進(jìn)程被殺掉時(shí),所有依賴于該進(jìn)程的服務(wù)也會(huì)停止運(yùn)行嚎杨。另外花鹅,服務(wù)并不會(huì)自動(dòng)開啟線程,所有的代碼都是默認(rèn)運(yùn)行在主線程當(dāng)中的枫浙。也就是說刨肃,我們需要在服務(wù)的內(nèi)部手動(dòng)創(chuàng)建子線程,并在這里執(zhí)行具體的任務(wù)箩帚,否則就有可能出現(xiàn)主線程被阻塞住的情況真友。

Android多線程編程

Android多線程編程與Java類似.新建一個(gè)類繼承Thread,重寫run(),其中編寫耗時(shí)邏輯.啟動(dòng)時(shí)只需new出實(shí)例,調(diào)用start()方法.或者實(shí)現(xiàn)Runable接口,實(shí)現(xiàn)run()方法.啟動(dòng)時(shí)通過

new Thread(myThread).start();

實(shí)現(xiàn).或者通過匿名類實(shí)現(xiàn)

new Thread(new Runnable() {
  @Override
  public void run() {
    // 處理具體的邏輯
  }
}).start();

9.2.2在子線程中更新UI

在子線程中更新UI是不安全的,因此必須在主線程中進(jìn)行.
子線程更新UI一次:

Process: com.wjoker.androidthreadtest, PID: 8037
android.view.ViewRootImpl$CalledFromWrongThreadException:
Only the original thread that created a view hierarchy can touch its views.

Android提供了異步消息處理機(jī)制,用于解決子線程中進(jìn)行UI操作的問題.

9.2.3解析異步消息處理機(jī)制

Android 中的異步消息處理主要由四個(gè)部分組成, Message紧帕、 Handler盔然、 MessageQueue 和Looper桅打。

  1. Message 是在線程之間傳遞的消息,它可以在內(nèi)部攜帶少量的信息愈案,用于在不同線程之間交換數(shù)據(jù)挺尾。上一小節(jié)中我們使用到了 Message 的 what 字段,除此之外還可以使用 arg1 和 arg2 字段來攜帶一些整型數(shù)據(jù)站绪,使用 obj 字段攜帶一個(gè) Object 對(duì)象遭铺。
  2. Handler 顧名思義也就是處理者的意思,它主要是用于發(fā)送和處理消息的恢准。發(fā)送消息一般是使用 Handler 的 sendMessage()方法魂挂,而發(fā)出的消息經(jīng)過一系列地輾轉(zhuǎn)處理后,最終會(huì)傳遞到 Handler 的 handleMessage()方法中馁筐。
  3. MessageQueue 是消息隊(duì)列的意思涂召,它主要用于存放所有通過 Handler 發(fā)送的消息。這部分消息會(huì)一直存在于消息隊(duì)列中眯漩,等待被處理芹扭。每個(gè)線程中只會(huì)有一個(gè) MessageQueue對(duì)象。
  4. Looper 是每個(gè)線程中的 MessageQueue 的管家赦抖,調(diào)用 Looper 的 loop()方法后舱卡,就會(huì)進(jìn)入到一個(gè)無限循環(huán)當(dāng)中,然后每當(dāng)發(fā)現(xiàn) MessageQueue 中存在一條消息队萤,就會(huì)將它取出轮锥,并傳遞到 Handler 的 handleMessage()方法中。每個(gè)線程中也只會(huì)有一個(gè) Looper 對(duì)象要尔。

首先需要在主線程當(dāng)中創(chuàng)建一個(gè) Handler 對(duì)象舍杜,并重寫handleMessage()方法。
然后當(dāng)子線程中需要進(jìn)行 UI 操作時(shí)赵辕,就創(chuàng)建一個(gè) Message 對(duì)象既绩,并通過 Handler 將這條消息發(fā)送出去。
之后這條消息會(huì)被添加到 MessageQueue 的隊(duì)列中等待被處理还惠,而 Looper 則會(huì)一直嘗試從 MessageQueue 中取出待處理消息饲握,最后分發(fā)回 Handler的 handleMessage()方法中。
由于 Handler 是在主線程中創(chuàng)建的蚕键,所以此時(shí) handleMessage()方法中的代碼也會(huì)在主線程中運(yùn)行救欧,于是我們?cè)谶@里就可以安心地進(jìn)行 UI 操作了。

9.2.4使用AsyncTask

Android提供AsyncTask在子線程中對(duì)UI進(jìn)行操作,其原理是基于異步消息處理機(jī)制.

由于 AsyncTask 是一個(gè)抽象類锣光,所以如果我們想使用它笆怠,就必須要?jiǎng)?chuàng)建一個(gè)子類去繼承它。在繼承時(shí)我們可以為 AsyncTask 類指定三個(gè)泛型參數(shù)誊爹,這三個(gè)參數(shù)的用途如下蹬刷。

  1. Params:在執(zhí)行 AsyncTask 時(shí)需要傳入的參數(shù)瓢捉,可用于在后臺(tái)任務(wù)中使用。
  2. Progress:后臺(tái)任務(wù)執(zhí)行時(shí)办成,如果需要在界面上顯示當(dāng)前的進(jìn)度泊柬,則使用這里指定的泛型作為進(jìn)度單位。
  3. Result:當(dāng)任務(wù)執(zhí)行完畢后诈火,如果需要對(duì)結(jié)果進(jìn)行返回,則使用這里指定的泛型作為返回值類型状答。
    示例:
class DownloadTask extends AsyncTask<Void, Integer, Boolean> {
    ……
}

這里我們把 AsyncTask 的第一個(gè)泛型參數(shù)指定為 Void冷守,表示在執(zhí)行 AsyncTask 的時(shí)候不需要傳入?yún)?shù)給后臺(tái)任務(wù)。第二個(gè)泛型參數(shù)指定為 Integer惊科,表示使用整型數(shù)據(jù)來作為進(jìn)度顯示單位拍摇。第三個(gè)泛型參數(shù)指定為 Boolean,則表示使用布爾型數(shù)據(jù)來反饋執(zhí)行結(jié)果馆截。

當(dāng)然充活,目前我們自定義的 DownloadTask 還是一個(gè)空任務(wù),并不能進(jìn)行任何實(shí)際的操作蜡娶,我們還需要去重寫 AsyncTask 中的幾個(gè)方法才能完成對(duì)任務(wù)的定制混卵。經(jīng)常需要去重寫的方法有以下四個(gè)。

  1. onPreExecute()
    這個(gè)方法會(huì)在后臺(tái)任務(wù)開始執(zhí)行之前調(diào)用窖张,用于進(jìn)行一些界面上的初始化操作幕随,比如顯示一個(gè)進(jìn)度條對(duì)話框等。
  2. doInBackground(Params...)
    這個(gè)方法中的所有代碼都會(huì)在子線程中運(yùn)行宿接,我們應(yīng)該在這里去處理所有的耗時(shí)任務(wù)赘淮。任務(wù)一旦完成就可以通過 return 語句來將任務(wù)的執(zhí)行結(jié)果返回,如果 AsyncTask 的第三個(gè)泛型參數(shù)指定的是 Void睦霎,就可以不返回任務(wù)執(zhí)行結(jié)果梢卸。注意,在這個(gè)方法中是不可以進(jìn)行 UI 操作的副女,如果需要更新 UI 元素蛤高,比如說反饋當(dāng)前任務(wù)的執(zhí)行進(jìn)度,可以調(diào)用 publishProgress(Progress...)方法來完成肮塞。
  3. onProgressUpdate(Progress...)
    當(dāng)在后臺(tái)任務(wù)中調(diào)用了 publishProgress(Progress...)方法后襟齿,這個(gè)方法就會(huì)很快被調(diào)用,方法中攜帶的參數(shù)就是在后臺(tái)任務(wù)中傳遞過來的枕赵。在這個(gè)方法中可以對(duì) UI 進(jìn)行操作猜欺,利用參數(shù)中的數(shù)值就可以對(duì)界面元素進(jìn)行相應(yīng)地更新。
  4. onPostExecute(Result)
    當(dāng)后臺(tái)任務(wù)執(zhí)行完畢并通過 return 語句進(jìn)行返回時(shí)拷窜,這個(gè)方法就很快會(huì)被調(diào)用开皿。返回的數(shù)據(jù)會(huì)作為參數(shù)傳遞到此方法中涧黄,可以利用返回的數(shù)據(jù)來進(jìn)行一些 UI 操作,比如說提醒任務(wù)執(zhí)行的結(jié)果赋荆,以及關(guān)閉掉進(jìn)度條對(duì)話框等笋妥。

示例:

class DownloadTask extends AsyncTask<Void, Integer, Boolean> {
  @Override
  protected void onPreExecute() {
    progressDialog.show(); // 顯示進(jìn)度對(duì)話框
  }
  @Override
  protected Boolean doInBackground(Void... params) {
    try {
      while (true) {
        int downloadPercent = doDownload(); // 這是一個(gè)虛構(gòu)的方法
        publishProgress(downloadPercent);
        if (downloadPercent >= 100) {
          break;
        }
      }
    } catch (Exception e) {
      return false;
    }
    return true;
  }
  @Override
  protected void onProgressUpdate(Integer... values) {
    // 在這里更新下載進(jìn)度
    progressDialog.setMessage("Downloaded " + values[0] + "%");
  }
  @Override
  protected void onPostExecute(Boolean result) {
    progressDialog.dismiss(); // 關(guān)閉進(jìn)度對(duì)話框
    // 在這里提示下載結(jié)果
    if (result) {
      Toast.makeText(context, "Download                 succeeded",Toast.LENGTH_SHORT).show();
     } else {
      Toast.makeText(context, " Download failed",Toast.LENGTH_SHORT).show();
    }
  }
}

在這個(gè) DownloadTask 中,我們?cè)?doInBackground()方法里去執(zhí)行具體的下載任務(wù)窄潭。這個(gè)方法里的代碼都是在子線程中運(yùn)行的春宣,因而不會(huì)影響到主線程的運(yùn)行。

注意這里虛構(gòu)了一個(gè)doDownload()方法嫉你,這個(gè)方法用于計(jì)算當(dāng)前的下載進(jìn)度并返回月帝,我們假設(shè)這個(gè)方法已經(jīng)存在了。在得到了當(dāng)前的下載進(jìn)度后幽污,下面就該考慮如何把它顯示到界面上了.

由于doInBackground()方法是在子線程中運(yùn)行的嚷辅,在這里肯定不能進(jìn)行 UI 操作,所以我們可以調(diào)用 publishProgress()方法并將當(dāng)前的下載進(jìn)度傳進(jìn)來距误,這樣 onProgressUpdate()方法就會(huì)很快被調(diào)用簸搞,在這里就可以進(jìn)行 UI 操作了。

當(dāng)下載完成后准潭, doInBackground()方法會(huì)返回一個(gè)布爾型變量趁俊,這樣 onPostExecute()方法就會(huì)很快被調(diào)用,這個(gè)方法也是在主線程中運(yùn)行的惋鹅。然后在這里我們會(huì)根據(jù)下載的結(jié)果來彈出相應(yīng)的 Toast 提示则酝,從而完成整個(gè) DownloadTask 任務(wù)。

簡(jiǎn)單來說闰集,使用 AsyncTask 的訣竅就是沽讹,在 doInBackground()方法中去執(zhí)行具體的耗時(shí)任務(wù),在 onProgressUpdate()方法中進(jìn)行 UI 操作武鲁,在 onPostExecute()方法中執(zhí)行一些任務(wù)的收尾工作爽雄。如果想要啟動(dòng)這個(gè)任務(wù),只需編寫以下代碼即可:

new DownloadTask().execute();

9.3服務(wù)的基本用法

9.3.1定義一個(gè)服務(wù)

定義一個(gè)類,繼承Service.實(shí)現(xiàn)onBind,onCreate,onStartCommand//啟動(dòng),onDestroy方法,

public class MyService extends Service {
  @Override
  public IBinder onBind(Intent intent) {
    return null;
  }
  @Override
  public void onCreate({
    super.onCreate();
  }
  @Override
  public int onStartCommand(Intent intent, int flags, int startId){
    return super.onStartCommand(intent, flags, startId);
  }
  @Override
  public void onDestroy() {
    super.onDestroy();
  }
}

要注冊(cè)服務(wù)后才可使用:

9.3.2啟動(dòng)和停止服務(wù).

啟動(dòng):

Intent startIntent = new Intent(this, MyService.class);
startService(startIntent); // 啟動(dòng)服務(wù)

停止:

Intent stopIntent = new Intent(this, MyService.class);
stopService(stopIntent); // 停止服務(wù)

9.3.3活動(dòng)和服務(wù)進(jìn)行通信

活動(dòng)和服務(wù)之間的通信可以通過onBind方法進(jìn)行

首先創(chuàng)建了一個(gè) ServiceConnection 的匿名類沐鼠,在里面重寫onServiceConnected()方法和 onServiceDisconnected()方法挚瘟,這兩個(gè)方法分別會(huì)在活動(dòng)與服務(wù)成功綁定以及解除綁定的時(shí)候調(diào)用。
在 onServiceConnected()方法中饲梭,我們又通過向下轉(zhuǎn)型得到了 DownloadBinder 的實(shí)例乘盖,有了這個(gè)實(shí)例, 活動(dòng)和服務(wù)之間的關(guān)系就變得非常緊密了°旧妫現(xiàn)在我們可以在活動(dòng)中根據(jù)具體的場(chǎng)景來調(diào)用 DownloadBinder 中的任何 public 方法订框,即實(shí)現(xiàn)了指揮服務(wù)干什么,服務(wù)就去干什么的功能兜叨。 這里仍然只是做了個(gè)簡(jiǎn)單的測(cè)試穿扳, 在onServiceConnected()方法中調(diào)用了 DownloadBinder 的 startDownload()和 getProgress()方法衩侥。當(dāng)然,現(xiàn)在活動(dòng)和服務(wù)其實(shí)還沒進(jìn)行綁定呢矛物,這個(gè)功能是在 Bind Service 按鈕的點(diǎn)擊事件里完成的茫死。可以看到履羞,這里我們?nèi)匀皇菢?gòu)建出了一個(gè) Intent 對(duì)象峦萎,然后調(diào)用 bindService()方法將 MainActivity 和 MyService 進(jìn)行綁定。 bindService()方法接收三個(gè)參數(shù)忆首,第一個(gè)參數(shù)就是剛剛構(gòu)建出的 Intent 對(duì)象骨杂,第二個(gè)參數(shù)是前面創(chuàng)建出的 ServiceConnection 的實(shí)例,第三個(gè)參數(shù)則是一個(gè)標(biāo)志位雄卷,這里傳入 BIND_AUTO_CREATE 表示在活動(dòng)和服務(wù)進(jìn)行綁定后自動(dòng)創(chuàng)建服務(wù)。 這會(huì)使得 MyService 中的 onCreate()方法得到執(zhí)行蛤售,但 onStartCommand()方法不會(huì)執(zhí)行丁鹉。然后如果我們想解除活動(dòng)和服務(wù)之間的綁定該怎么辦呢?調(diào)用一下 unbindService()方法就可以了悴能,這也是 Unbind Service 按鈕的點(diǎn)擊事件里實(shí)現(xiàn)的功能揣钦。

9.4服務(wù)的生命周期

前面我們使用到的 onCreate()、 onStartCommand()漠酿、 onBind()和 onDestroy()等方法都是在服務(wù)的生命周期內(nèi)可能回調(diào)的方法冯凹。

一旦在項(xiàng)目的任何位置調(diào)用了 Context 的 startService()方法,相應(yīng)的服務(wù)就會(huì)啟動(dòng)起來炒嘲,并回調(diào) onStartCommand()方法宇姚。如果這個(gè)服務(wù)之前還沒有創(chuàng)建過, onCreate()方法會(huì)先于onStartCommand()方法執(zhí)行夫凸。服務(wù)啟動(dòng)了之后會(huì)一直保持運(yùn)行狀態(tài)浑劳,直到 stopService()或stopSelf()方法被調(diào)用塘慕。注意雖然每調(diào)用一次 startService()方法树碱, onStartCommand()就會(huì)執(zhí)行一次南蓬,但實(shí)際上每個(gè)服務(wù)都只會(huì)存在一個(gè)實(shí)例屡拨。所以不管你調(diào)用了多少次 startService()方法乞巧,只需調(diào)用一次 stopService()或 stopSelf()方法谭网,服務(wù)就會(huì)停止下來了裕坊。

另外滋饲,還可以調(diào)用 Context 的 bindService()來獲取一個(gè)服務(wù)的持久連接桶现,這時(shí)就會(huì)回調(diào)服務(wù)中的 onBind()方法躲雅。類似地,如果這個(gè)服務(wù)之前還沒有創(chuàng)建過巩那, onCreate()方法會(huì)先于onBind()方法執(zhí)行吏夯。之后此蜈,調(diào)用方可以獲取到 onBind()方法里返回的 IBinder 對(duì)象的實(shí)例,這樣就能自由地和服務(wù)進(jìn)行通信了噪生。只要調(diào)用方和服務(wù)之間的連接沒有斷開裆赵,服務(wù)就會(huì)一直保持運(yùn)行狀態(tài)。

當(dāng)調(diào)用了 startService()方法后跺嗽,又去調(diào)用 stopService()方法战授,這時(shí)服務(wù)中的 onDestroy()方法就會(huì)執(zhí)行,表示服務(wù)已經(jīng)銷毀了桨嫁。類似地植兰,當(dāng)調(diào)用了 bindService()方法后,又去調(diào)用unbindService()方法璃吧, onDestroy()方法也會(huì)執(zhí)行楣导,這兩種情況都很好理解。但是需要注意畜挨,我們是完全有可能對(duì)一個(gè)服務(wù)既調(diào)用了 startService()方法筒繁,又調(diào)用了 bindService()方法的,這種情況下該如何才能讓服務(wù)銷毀掉呢巴元?根據(jù) Android 系統(tǒng)的機(jī)制毡咏,一個(gè)服務(wù)只要被啟動(dòng)或者被綁定了之后,就會(huì)一直處于運(yùn)行狀態(tài)逮刨,必須要讓以上兩種條件同時(shí)不滿足呕缭,服務(wù)才能被銷毀。所以修己,這種情況下要同時(shí)調(diào)用 stopService()和 unbindService()方法恢总, onDestroy()方法才會(huì)執(zhí)行。

9.5服務(wù)的更多技巧

9.5.1使用前臺(tái)服務(wù)

大部分服務(wù)都在后臺(tái)運(yùn)行,但服務(wù)的系統(tǒng)優(yōu)先級(jí)較低,當(dāng)內(nèi)存不足時(shí)可能回收后臺(tái)運(yùn)行的服務(wù),如果需要服務(wù)一直保持運(yùn)行,可以使用前臺(tái)服務(wù).
前臺(tái)服務(wù)會(huì)有一個(gè)正在運(yùn)行的圖標(biāo)在系統(tǒng)的狀態(tài)欄顯示,下拉后可以看到更加詳細(xì)的信息.
在Service的onCreate()中使用通知,最后使用startForeground()方法.該方法接受兩個(gè)參數(shù),一個(gè)是通知的ID,另一個(gè)接受構(gòu)建的Notification對(duì)象.

public void onCreate(){
    Log.e("wyxjoker", "onCreate executed");
    super.onCreate();
    Intent notificationIntent = new Intent(this,MainActivity.class);   
    PendingIntent pendingIntent = PendingIntent.getActivity(this,0,notificationIntent,0);
    Notification notification = new Notification.Builder(this)
            .setAutoCancel(true)
            .setContentTitle("This is a title")
            .setContentText("This is content")
            .setContentIntent(pendingIntent)
            .setSmallIcon(R.mipmap.ic_launcher)
            .setWhen(System.currentTimeMillis())
            .build();
    startForeground(1,notification);
}

9.5.2使用IntentService

服務(wù)中的嗲嗎都是默認(rèn)運(yùn)行在主線程中,如果服務(wù)里處理耗時(shí)操作,容易出現(xiàn)ANR(Application Not Responding).因此需要服務(wù)的每個(gè)具體方法里開啟子線程,處理耗時(shí)操作.

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
  new Thread(new Runnable() {
    @Override
    public void run() {
      // 處理具體的邏輯
      stopSelf();
    }
  }).start();
  return super.onStartCommand(intent, flags, startId);
}

Android提供了IntentService類用于創(chuàng)建異步,會(huì)自動(dòng)停止的服務(wù).
新建類,繼承IntentService在onHandleIntent(Intent intent)中寫邏輯.

public class MyIntentService extends IntentService {
  public MyIntentService() {
    super("MyIntentService"); // 調(diào)用父類的有參構(gòu)造函數(shù)
  }
  @Override
  protected void onHandleIntent(Intent intent) {
    // 打印當(dāng)前線程的id
    Log.d("MyIntentService", "Thread id is " +     Thread.currentThread().getId());
  }
  @Override
  public void onDestroy() {
    super.onDestroy();
    Log.d("MyIntentService", "onDestroy executed");
  }
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末睬愤,一起剝皮案震驚了整個(gè)濱河市离熏,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌戴涝,老刑警劉巖滋戳,帶你破解...
    沈念sama閱讀 216,997評(píng)論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異啥刻,居然都是意外死亡奸鸯,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,603評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門可帽,熙熙樓的掌柜王于貴愁眉苦臉地迎上來娄涩,“玉大人,你說我怎么就攤上這事⌒罴穑” “怎么了扬虚?”我有些...
    開封第一講書人閱讀 163,359評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)球恤。 經(jīng)常有香客問我辜昵,道長(zhǎng),這世上最難降的妖魔是什么咽斧? 我笑而不...
    開封第一講書人閱讀 58,309評(píng)論 1 292
  • 正文 為了忘掉前任堪置,我火速辦了婚禮,結(jié)果婚禮上张惹,老公的妹妹穿的比我還像新娘舀锨。我一直安慰自己,他們只是感情好宛逗,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,346評(píng)論 6 390
  • 文/花漫 我一把揭開白布坎匿。 她就那樣靜靜地躺著,像睡著了一般雷激。 火紅的嫁衣襯著肌膚如雪碑诉。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,258評(píng)論 1 300
  • 那天侥锦,我揣著相機(jī)與錄音,去河邊找鬼德挣。 笑死恭垦,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的格嗅。 我是一名探鬼主播番挺,決...
    沈念sama閱讀 40,122評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼屯掖!你這毒婦竟也來了玄柏?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,970評(píng)論 0 275
  • 序言:老撾萬榮一對(duì)情侶失蹤贴铜,失蹤者是張志新(化名)和其女友劉穎粪摘,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體绍坝,經(jīng)...
    沈念sama閱讀 45,403評(píng)論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡徘意,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,596評(píng)論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了轩褐。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片椎咧。...
    茶點(diǎn)故事閱讀 39,769評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖把介,靈堂內(nèi)的尸體忽然破棺而出勤讽,到底是詐尸還是另有隱情蟋座,我是刑警寧澤,帶...
    沈念sama閱讀 35,464評(píng)論 5 344
  • 正文 年R本政府宣布脚牍,位于F島的核電站向臀,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏莫矗。R本人自食惡果不足惜飒硅,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,075評(píng)論 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望作谚。 院中可真熱鬧三娩,春花似錦、人聲如沸妹懒。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,705評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽眨唬。三九已至会前,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間匾竿,已是汗流浹背瓦宜。 一陣腳步聲響...
    開封第一講書人閱讀 32,848評(píng)論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留岭妖,地道東北人临庇。 一個(gè)月前我還...
    沈念sama閱讀 47,831評(píng)論 2 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像昵慌,于是被迫代替她去往敵國和親假夺。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,678評(píng)論 2 354

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