『CoreBluetooth』8. 后臺(tái)運(yùn)行藍(lán)牙服務(wù)

這是 CoreBluetooth 系列的最后一篇,其他文章可查看:

CoreBluetooth1 初識(shí)

CoreBluetooth2 作為 Central 時(shí)的數(shù)據(jù)讀寫

CoreBluetooth3 作為 Central 時(shí)的數(shù)據(jù)讀寫(補(bǔ)充)

CoreBluetooth4 作為 Central 時(shí)的數(shù)據(jù)讀寫(最佳實(shí)踐)

CoreBluetooth5 作為 Central 時(shí)的數(shù)據(jù)讀寫(OTA 固件升級(jí)與文件傳輸)

CoreBluetooth6 作為 Peripheral 時(shí)的請(qǐng)求響應(yīng)

CoreBluetooth7 作為 Peripheral 時(shí)的請(qǐng)求響應(yīng)(最佳實(shí)踐)

對(duì)于 iOS app 來說夕凝,知道現(xiàn)在是運(yùn)行在前臺(tái)和后臺(tái)是至關(guān)重要的或链。因?yàn)楫?dāng)程序掛起后轧铁,對(duì)資源的使用是相當(dāng)有限的乎赴。關(guān)于多任務(wù)的介紹摔竿,可以看app 開發(fā)手冊(cè)间坐。

默認(rèn)情況下灾挨,Core Bluetooth 是不會(huì)在后臺(tái)運(yùn)行的(無論是 central 還是 peripheral)。但你也可以配置在 app 收到事件后竹宋,從掛起狀態(tài)喚醒劳澄。即使程序不是完全的支持后臺(tái)模式,也可以要求在有重要事件時(shí)接收系統(tǒng)通知蜈七。

即使在以上兩種情況下(完全允許后臺(tái)和部分允許后臺(tái))秒拔,程序也有可能不會(huì)永遠(yuǎn)掛起。在前臺(tái)程序需要更多內(nèi)存時(shí)飒硅,被掛起的程序很有可能會(huì)被強(qiáng)制退出砂缩,那樣會(huì)斷開所有的連接作谚。從 iOS 7 開始,能夠先保存狀態(tài)(無論是 central 還是 peripheral)庵芭,并在重新打開 app 時(shí)還原這些狀態(tài)妹懒。通過這一?特性,就可以做長(zhǎng)時(shí)間操作了双吆。

運(yùn)行在前臺(tái)的 app (Foreground-Only)

除非去申請(qǐng)后臺(tái)權(quán)限眨唬,否則 app 都是只在前臺(tái)運(yùn)行的,程序在進(jìn)入后臺(tái)不久便會(huì)切換到掛起狀態(tài)伊诵。掛起后单绑,程序?qū)o法再接收任何藍(lán)牙事件。

對(duì)于 central 來說曹宴,掛起將無法再進(jìn)行掃描和搜索 peripheral搂橙。對(duì)于 peripheral 來說,將無法再發(fā)起廣播笛坦,central 也無法再訪問動(dòng)態(tài)變化的 characteristic 數(shù)據(jù)区转,訪問將返回 error。

根據(jù)不同情況版扩,這種機(jī)制會(huì)影響程序在以下幾個(gè)方面的運(yùn)用废离。你正在讀取 peripheral 的數(shù)據(jù),結(jié)果程序被掛起了(可能是用戶切換到了另外一個(gè) app)礁芦,此時(shí)連接會(huì)被斷開蜻韭,但是要直到程序重新喚醒時(shí),你才知道被斷開了柿扣。

利用連接 Peripheral 時(shí)的選項(xiàng)

Foreground-Only app 在掛起的時(shí)候肖方,便會(huì)加入到系統(tǒng)的一個(gè)隊(duì)列中,當(dāng)程序重新喚醒時(shí)未状,系統(tǒng)便會(huì)通知程序俯画。Core Bluetooth 會(huì)在程序中包含 central 時(shí),給用戶以提示司草。用戶可根據(jù)提示來判斷是否要喚醒該 app艰垂。

你可以利用 central 在連接 peripheral 時(shí)的方法connectPeripheral:options:中的options來觸發(fā)提示:

CBConnectPeripheralOptionNotifyOnConnectionKey—— 在連接成功后,程序被掛起埋虹,?給出系統(tǒng)提示猜憎。

CBConnectPeripheralOptionNotifyOnDisconnectionKey—— 在程序掛起,藍(lán)牙連接斷開時(shí)搔课,給出系統(tǒng)提示拉宗。

CBConnectPeripheralOptionNotifyOnNotificationKey—— 在程序掛起后,收到 peripheral 數(shù)據(jù)時(shí),給出系統(tǒng)提示旦事。

Core Bluetooth 后臺(tái)模式

如果你想讓你的 app 能在后臺(tái)運(yùn)行藍(lán)牙魁巩,那么必須在info.plist中打開藍(lán)牙的后臺(tái)運(yùn)行模式。當(dāng)配置之后姐浮,收到相關(guān)事件便會(huì)從后臺(tái)喚醒谷遂。這一機(jī)制對(duì)定期接收數(shù)據(jù)的 app 很有用,比如心率監(jiān)測(cè)器卖鲤。

下面會(huì)介紹兩種后臺(tái)模式肾扰,一種是作為 central 的,一種是作為 peripheral 的蛋逾,如果 app 兩種角色都有集晚,那則需要開啟兩種模式。配置即是在info.plist中添加UIBackgroundModeskey区匣,類型為數(shù)組偷拔,value 則根據(jù)你當(dāng)前角色來選擇:

bluetooth-central—— 即 Central。

bluetooth-peripheral—— 即 Peripheral亏钩。

這個(gè)配置在 Xcode 中莲绰,可以在 Capabilities 中進(jìn)行配置,而不用直接面對(duì) key-value姑丑。如果要看到 key-value蛤签,可以在info.plist中打開查看。

作為 Central 的后臺(tái)模式

如果在info.plist中配置了UIBackgroundModes–bluetooth-central栅哀,那么系統(tǒng)則允許程序在后臺(tái)處理藍(lán)牙相關(guān)事件震肮。在程序進(jìn)入后臺(tái)后,依然能掃描留拾、搜索 peripheral戳晌,并且還能進(jìn)行數(shù)據(jù)交互。當(dāng)CBCentralManagerDelegate和CBPeripheralDelegate的代理方法被調(diào)用時(shí)间驮,系統(tǒng)將會(huì)喚醒程序。此時(shí)允許你去處理重要的事件马昨,比如:連接的建立或斷開竞帽,peripheral 發(fā)送了數(shù)據(jù),central manager 的狀態(tài)改變鸿捧。

雖然此時(shí)程序能在后臺(tái)運(yùn)行屹篓,但是對(duì) peripheral 的掃描和在前臺(tái)時(shí)是不一樣的。實(shí)際情況是這樣的:

設(shè)置的CBCentralManagerScanOptionAllowDuplicatesKey將失效匙奴,并將發(fā)現(xiàn)的多個(gè) peripheral 廣播的事件合并為一個(gè)堆巧。

如果全部的 app 都在后臺(tái)搜索 peripheral,那么每次搜索的時(shí)間間隔會(huì)更大。這會(huì)導(dǎo)致搜索到 peripheral 的時(shí)間變長(zhǎng)谍肤。

這些相應(yīng)的調(diào)整會(huì)減少無線電使用啦租,并提升續(xù)航能力。

作為 peripheral 的后臺(tái)模式

作為 peripheral 時(shí)荒揣,如果需要支持后臺(tái)模式篷角,則在info.plist中配置UIBackgroundModes–bluetooth-peripheral。配置后系任,系統(tǒng)會(huì)在有讀寫請(qǐng)求和訂閱事件時(shí)恳蹲,喚醒程序。

在后臺(tái)俩滥,除了允許處理讀寫請(qǐng)求和訂閱事件外嘉蕾,Core Bluetooth 框架還允許 peripheral 發(fā)出廣播。同樣霜旧,廣播事件也有前后臺(tái)區(qū)別错忱。在后臺(tái)發(fā)起時(shí)是這樣的:

CBAdvertisementDataLocalNameKey將失效,在廣播時(shí)颁糟,廣播數(shù)據(jù)將不再包含 peripheral 的名字航背。

被CBAdvertisementDataServiceUUIDsKey修飾的 UUID 數(shù)組將會(huì)被放到 overflow 區(qū)域中,意味著只能被明確標(biāo)識(shí)了搜索 service UUID 的 iOS 設(shè)備找到棱貌。

如果所有 app 都在后臺(tái)發(fā)起廣播玖媚,那么發(fā)起頻率會(huì)降低。

巧妙的使用后臺(tái)模式

雖然程序支持一個(gè)或多個(gè) Core Bluetooth 服務(wù)在后臺(tái)運(yùn)行婚脱,但也不要濫用今魔。因?yàn)樗{(lán)牙服務(wù)會(huì)占用 iOS 設(shè)備的無線電資源,這也會(huì)間接影響到續(xù)航能力障贸,所以盡可能少的去使用后臺(tái)模式错森。app 會(huì)喚醒程序并處理相關(guān)事務(wù),完成后又會(huì)快速回到掛起狀態(tài)篮洁。

無論是 central 還是 peripheral涩维,要支持后臺(tái)模式都應(yīng)該遵循以下幾點(diǎn):

程序應(yīng)該提供 UI,讓用戶決定是否要在后臺(tái)運(yùn)行袁波。

一旦程序在后臺(tái)被喚醒瓦阐,程序只有 10s 的時(shí)間來處理相關(guān)事務(wù)。所以應(yīng)該在程序再次掛起前處理完事件篷牌。后臺(tái)運(yùn)行的太耗時(shí)的程序會(huì)被系統(tǒng)強(qiáng)制關(guān)閉進(jìn)程睡蟋。

處理無關(guān)的事件不應(yīng)該喚醒程序。

和后臺(tái)運(yùn)行的更多介紹枷颊,可以查看App Programming Guide for iOS戳杀。

處理常駐后臺(tái)任務(wù)

某些 app 可能需要 Core Bluetooth 常駐后臺(tái)该面,比如,一款用 BLE 技術(shù)和門鎖通信的 app信卡。當(dāng)用戶離開時(shí)隔缀,自動(dòng)上鎖,回來時(shí)坐求,自動(dòng)開鎖(即使程序運(yùn)行在后臺(tái))蚕泽。當(dāng)用戶離開時(shí),可能已超出藍(lán)牙連接范圍桥嗤,所以沒辦法給鎖通信须妻。此時(shí)可以調(diào)用CBCentralManager的connectPeripheral:options:方法,因?yàn)樵摲椒]有超時(shí)設(shè)置泛领,所以荒吏,在用戶返回時(shí),可以重新連接到鎖渊鞋。

但是還有這樣的情形:用戶可能離開家好幾天绰更,并且在這期間,程序已經(jīng)被完全退出了锡宋。那么用戶再次回家時(shí)儡湾,就不能自動(dòng)開鎖。對(duì)于這類 app 來說执俩,常駐后臺(tái)操作就顯得尤為重要徐钠。

狀態(tài)保存與恢復(fù)

因?yàn)闋顟B(tài)的保存和恢復(fù) Core Bluetooth 都為我們封裝好了,所以我們只需要選擇是否需要這個(gè)特性即可役首。系統(tǒng)會(huì)保存當(dāng)前 central manager 或 peripheral manager尝丐,并且繼續(xù)執(zhí)行藍(lán)牙相關(guān)事件(及時(shí)程序已經(jīng)不再運(yùn)行)。一旦事件執(zhí)行完畢衡奥,系統(tǒng)會(huì)在后臺(tái)重啟 app爹袁,這是你有機(jī)會(huì)去存儲(chǔ)當(dāng)前狀態(tài),并且處理一些事物矮固。在之前提到的 “門鎖” 的例子中失息,系統(tǒng)會(huì)監(jiān)視連接請(qǐng)求,并在centralManager:didConnectPeripheral:回調(diào)時(shí)档址,重啟 app盹兢,在用戶回家后,連接操作結(jié)束辰晕。

Core Bluetooth 的狀態(tài)保存于恢復(fù)在設(shè)備作為 central蛤迎、peripheral 或者這兩種角色時(shí)确虱,都可用含友。在設(shè)備作為 central 并添加了狀態(tài)保存與恢復(fù)支持后,如果 app 被強(qiáng)行關(guān)閉進(jìn)程,系統(tǒng)會(huì)自動(dòng)保存 central manager 的狀態(tài)(如果 app 有多個(gè) central manager窘问,你可以選擇哪一個(gè)需要系統(tǒng)保存)辆童。對(duì)于CBCentralManager,系統(tǒng)會(huì)保存以下信息:

central 需要掃描的 service(包括掃描時(shí)惠赫,配置的 options)

central 準(zhǔn)備連接或已經(jīng)連接的 peripheral

central 訂閱的 characteristic

對(duì)于 peripheral 來說把鉴,情況也差不多。系統(tǒng)對(duì)CBPeripheralManager的處理方式如下:

peripheral 在廣播的數(shù)據(jù)

peripheral 存入的 service 和 characteristic 的樹形結(jié)構(gòu)

已經(jīng)被 central 訂閱了的 characteristic 的值

當(dāng)系統(tǒng)在后臺(tái)重新加載程序后(可能是因?yàn)檎业搅艘业?peripheral)儿咱,你可以重新實(shí)例化 central manager 或 peripheral 并恢復(fù)他們的狀態(tài)庭砍。接下來會(huì)詳細(xì)介紹如何存儲(chǔ)和恢復(fù)狀態(tài)。

添加狀態(tài)存儲(chǔ)和恢復(fù)支持

狀態(tài)的存儲(chǔ)和恢復(fù)功能在 Core Bluetooth 中是可選的混埠,添加支持可以通過以下幾個(gè)步驟:

(必須)在初始化 central manager 或 peripheral manager 時(shí)怠缸,要選擇是否需要支持。會(huì)在文后的【選擇支持存儲(chǔ)和恢復(fù)】中介紹钳宪。

(必須)在系統(tǒng)從后臺(tái)重新加載程序時(shí)揭北,重新初始化 central manager 或 peripheral manager。會(huì)在文后的【重新初始化 central manager 和 peripheral manager】中介紹吏颖。

(必須)實(shí)現(xiàn)恢復(fù)狀態(tài)相關(guān)的代理方法搔体。會(huì)在文后的【 實(shí)現(xiàn)恢復(fù)狀態(tài)的代理方法】中介紹。

(可選)更新 central manager 或 peripheral manager 的初始化過程半醉。會(huì)在文后的【更新 manager 初始化過程】中介紹疚俱。

選擇支持存儲(chǔ)和恢復(fù)

如果要支持存儲(chǔ)和恢復(fù),則需要在初始化 manager 的時(shí)候給一個(gè) restoration identifier奉呛。restoration identifier 是 string 類型计螺,并標(biāo)識(shí)了 app 中的 central manager 或 peripheral manager。這個(gè) string 很重要瞧壮,它將會(huì)告訴 Core Bluetooth 需要存儲(chǔ)狀態(tài)登馒,畢竟 Core Bluetooth 恢復(fù)有 identifier 的對(duì)象。

例如咆槽,在 central 端陈轿,要想支持該特性,可以在調(diào)用CBCentralManager的初始化方法時(shí)秦忿,配置CBCentralManagerOptionRestoreIdentifierKey:

myCentralManager = [[CBCentralManager alloc] initWithDelegate:selfqueue:niloptions:@{CBCentralManagerOptionRestoreIdentifierKey :@"myCentralManagerIdentifier"}];

雖然以上代碼沒有展示出來翁授,其實(shí)在 peripheral manager 中要設(shè)置 identifier 也是這樣的茫打。只是在初始化時(shí),將 key 改成了CBPeripheralManagerOptionRestoreIdentifierKey。

因?yàn)槌绦蚩梢杂卸鄠€(gè)CBCentralManager和CBPeripheralManager露氮,所以要確保每個(gè) identifier 都是唯一的。

重新初始化 central manager 和 peripheral manager

當(dāng)系統(tǒng)重新在后臺(tái)加載程序時(shí)找前,首先需要做的即根據(jù)存儲(chǔ)的 identifier,重新初始化 central manager 或 peripheral manager罗售。如果你只有一個(gè) manager,并且 manager 存在于 app 生命周期中钩述,那這個(gè)步驟就不需要做什么了寨躁。

如果 app 中包含多個(gè) manager,或者 manager 不是在整個(gè) app 生命周期中都存在的牙勘,那 app 就必須要區(qū)分你要重新初始化哪個(gè) manager 了职恳。你可以通過從 app delegate 中的application:didFinishLaunchingWithOptions:中取出 key(UIApplicationLaunchOptionsBluetoothCentralsKey或UIApplicationLaunchOptionsBluetoothPeripheralsKey) ?中的 value(數(shù)組類型)來得到程序退出之前存儲(chǔ)的 manager identifier 列表:

- (BOOL)application:(UIApplication*)applicationdidFinishLaunchingWithOptions:(NSDictionary*)launchOptions {NSArray*centralManagerIdentifiers = launchOptions[UIApplicationLaunchOptionsBluetoothCentralsKey];returnYES;}

拿到這個(gè)列表后,就可以通過循環(huán)來重新初始化所有的 manager 了方面。

實(shí)現(xiàn)恢復(fù)狀態(tài)的代理方法

在重新初始化 manager 之后放钦,接下來需要同步 Core Bluetooth 存儲(chǔ)的他們的狀態(tài)。要想弄清楚在程序被退出時(shí)都在做些什么恭金,就需要正確的實(shí)現(xiàn)代理方法最筒。對(duì)于 central manager 來說,需要實(shí)現(xiàn)centralManager:willRestoreState:蔚叨;對(duì)于 peripheral manager 來說床蜘,需要實(shí)現(xiàn)peripheralManager:willRestoreState:。

注意:如果選擇存儲(chǔ)和恢復(fù)狀態(tài)蔑水,當(dāng)系統(tǒng)在后臺(tái)重新加載程序時(shí)邢锯,首先調(diào)用的方法是centralManager:willRestoreState:或peripheralManager:willRestoreState:。如果沒有選擇存儲(chǔ)的恢復(fù)狀態(tài)(或者喚醒時(shí)沒有什么內(nèi)容需要恢復(fù))搀别,那么首先調(diào)用的方法是centralManagerDidUpdateState:或peripheralManagerDidUpdateState:丹擎。

無論是以上哪種代理方法,最后一個(gè)參數(shù)都是一個(gè)包含程序退出前狀態(tài)的字典歇父。字典中蒂培,可用的 key ,central 端有:

NSString*constCBCentralManagerRestoredStatePeripheralsKey;NSString*constCBCentralManagerRestoredStateScanServicesKey;NSString*constCBCentralManagerRestoredStateScanOptionsKey;

peripheral 端有:

NSString*constCBPeripheralManagerRestoredStateServicesKey;NSString*constCBPeripheralManagerRestoredStateAdvertisementDataKey;

要恢復(fù) central manager 的狀態(tài)榜苫,可以用centralManager:willRestoreState:返回字典中的 key 來得到护戳。假如說 central manager 有想要或者已經(jīng)連接的 peripheral,那么可以通過CBCentralManagerRestoredStatePeripheralsKey對(duì)應(yīng)得到的 peripheral (CBPeripheral對(duì)象)數(shù)組來得到垂睬。

- (void)centralManager:(CBCentralManager *)central? ? ? willRestoreState:(NSDictionary*)state {NSArray*peripherals = state[CBCentralManagerRestoredStatePeripheralsKey];}

具體要對(duì)拿到的 peripheral 數(shù)組做什么就要根據(jù)需求來了媳荒。如果這是個(gè) central manager 搜索到的 peripheral 數(shù)組,那就可以存儲(chǔ)這個(gè)數(shù)組的引用驹饺,并且開始建立連接了(注意給這些 peripheral 設(shè)置代理钳枕,否則連接后不會(huì)走 peripheral 的代理方法)。

恢復(fù) peripheral manager 的狀態(tài)和 central manager 的方式類似赏壹,就只是把代理方法換成了peripheralManager:willRestoreState:鱼炒,并且使用對(duì)應(yīng)的 key 即可。

更新 manager 初始化過程

在實(shí)現(xiàn)了全部的必須步驟后蝌借,你可能想要更新 manager 的初始化過程昔瞧。雖然這是個(gè)可選的操作俐巴,但是它對(duì)確保各種操作能正常進(jìn)行尤為重要。假如硬爆,你的應(yīng)用在 central 和 peripheral 做數(shù)據(jù)交互時(shí),被強(qiáng)制退出了擎鸠。即使 app 最后恢復(fù)狀態(tài)時(shí)缀磕,找到了這個(gè) peripheral,那你也不知道 central 和這個(gè) peripheral 當(dāng)時(shí)的具體狀態(tài)劣光。但其實(shí)我們?cè)诨謴?fù)時(shí)袜蚕,是想恢復(fù)到程序被強(qiáng)制退出前的那一步。

這個(gè)需求绢涡,可以在代理方法centralManagerDidUpdateState:中牲剃,通過發(fā)現(xiàn)恢復(fù)的 peripheral 是否之前已經(jīng)成功連接來實(shí)現(xiàn):

NSUIntegerserviceUUIDIndex = [peripheral.services indexOfObjectPassingTest:^BOOL(CBService *obj,NSUIntegerindex,BOOL*stop) {return[obj.UUID isEqual:myServiceUUIDString];}];if(serviceUUIDIndex ==NSNotFound) {? ? [peripheral discoverServices:@[myServiceUUIDString]];}

上面的代碼描述了,當(dāng)系統(tǒng)在完成搜索 service 之后才退出的程序雄可,可以通過調(diào)用discoverServices:方法來恢復(fù) peripheral 的數(shù)據(jù)凿傅。如果 app 成功搜索到 service,你可以是否能搜索到需要的 characteristic(或者已經(jīng)訂閱過)数苫。通過更新初始化過程聪舒,可以確保在正確的時(shí)間點(diǎn),調(diào)用正確的方法虐急。

最后

到這里箱残,對(duì) Core Bluetooth 的理解就暫告一段落,如果有什么問題或建議止吁,歡迎評(píng)論被辑。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市敬惦,隨后出現(xiàn)的幾起案子盼理,更是在濱河造成了極大的恐慌,老刑警劉巖俄删,帶你破解...
    沈念sama閱讀 211,639評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件榜揖,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡抗蠢,警方通過查閱死者的電腦和手機(jī)举哟,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,277評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來迅矛,“玉大人妨猩,你說我怎么就攤上這事』喟” “怎么了壶硅?”我有些...
    開封第一講書人閱讀 157,221評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵威兜,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我庐椒,道長(zhǎng)椒舵,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,474評(píng)論 1 283
  • 正文 為了忘掉前任约谈,我火速辦了婚禮笔宿,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘棱诱。我一直安慰自己泼橘,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,570評(píng)論 6 386
  • 文/花漫 我一把揭開白布迈勋。 她就那樣靜靜地躺著炬灭,像睡著了一般。 火紅的嫁衣襯著肌膚如雪靡菇。 梳的紋絲不亂的頭發(fā)上重归,一...
    開封第一講書人閱讀 49,816評(píng)論 1 290
  • 那天,我揣著相機(jī)與錄音厦凤,去河邊找鬼提前。 笑死,一個(gè)胖子當(dāng)著我的面吹牛泳唠,可吹牛的內(nèi)容都是我干的狈网。 我是一名探鬼主播,決...
    沈念sama閱讀 38,957評(píng)論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼笨腥,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼拓哺!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起脖母,我...
    開封第一講書人閱讀 37,718評(píng)論 0 266
  • 序言:老撾萬榮一對(duì)情侶失蹤士鸥,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后谆级,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體烤礁,經(jīng)...
    沈念sama閱讀 44,176評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,511評(píng)論 2 327
  • 正文 我和宋清朗相戀三年肥照,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了脚仔。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,646評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡舆绎,死狀恐怖鲤脏,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤猎醇,帶...
    沈念sama閱讀 34,322評(píng)論 4 330
  • 正文 年R本政府宣布窥突,位于F島的核電站,受9級(jí)特大地震影響硫嘶,放射性物質(zhì)發(fā)生泄漏阻问。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,934評(píng)論 3 313
  • 文/蒙蒙 一沦疾、第九天 我趴在偏房一處隱蔽的房頂上張望称近。 院中可真熱鬧,春花似錦曹鸠、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,755評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至晾蜘,卻和暖如春邻眷,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背剔交。 一陣腳步聲響...
    開封第一講書人閱讀 31,987評(píng)論 1 266
  • 我被黑心中介騙來泰國(guó)打工肆饶, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人岖常。 一個(gè)月前我還...
    沈念sama閱讀 46,358評(píng)論 2 360
  • 正文 我出身青樓驯镊,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親竭鞍。 傳聞我的和親對(duì)象是個(gè)殘疾皇子板惑,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,514評(píng)論 2 348

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