Android知識體系(2)

Android知識體系(1)
Android知識體系(2)

十一.Handler機(jī)制

1、定義&作用

定義:Android中線程之間消息傳遞、異步通信的機(jī)制。
作用:將工作線程的消息傳遞到UI主線程中,從而是實(shí)現(xiàn)工作線程對主線程的更新,避免線程操作的不安全。

2、原理

相關(guān)組件:
· Handler:消息處理者,添加消息Message到MessageQueue中,再通過Looper循環(huán)取出消息。
主要方法:handler.post()、handler.sendMessage()、handler.dispatchMessage()、handler.handleMessage()
· Message:存儲需要操作的數(shù)據(jù)
· MessageQueue:存放消息的數(shù)據(jù)結(jié)構(gòu)
主要方法:queue.enqueueMessage()
· Looper:消息循環(huán)
主要方法:looper.prepare()、looper.loop()

在主線程中創(chuàng)建Looper和MessageQueue,通過handler.sendMessage或者h(yuǎn)andler.post發(fā)送消息進(jìn)入MessageQueue。
Looper不斷的循環(huán)從消息隊(duì)列中取出消息,發(fā)送給消息創(chuàng)建者h(yuǎn)andler。handler接收消息,在handleMessage方法中處理。


27C8A243-B380-4249-A873-FBEAC76DCA09.png

相關(guān)資料文章:
Android異步通信:手把手帶你深入分析 Handler機(jī)制源碼
Android異步通信:這是一份Handler消息傳遞機(jī)制的使用教程
Android 多線程:你的 Handler 內(nèi)存泄露 了嗎?

十二.自定義view

  • 如圖所示

    • img
  • View的繪制是從上往下一層層迭代下來的。DecorView-->ViewGroup(--->ViewGroup)-->View ,按照這個(gè)流程從上往下,依次measure(測量),layout(布局),draw(繪制)。

    • img
  • View分類:(1)單一視圖 (2)視圖組ViewGroup
    無論是measure過程、layout過程、draw過程都是從樹的根節(jié)點(diǎn)開始(即樹形結(jié)構(gòu)的頂端),view的位置是相對于父view而言的。

1、onMeasure 測量

作用:決定view的大小

  • onMeasure 過程
    頂層ViewGroup->measure->onMeasure->measureChildren->子View->measure->onMeasure->測量完畢
    ViewGroup的測量過程需要重寫onMeasure方法,根據(jù)布局的特性重寫。

  • measureSpec測量規(guī)格
    measureSpec(測量規(guī)格 32位的int值) = mode(測量模式 高2位 31.32位) + size(具體大小 低30位)
    MeasureSpec.getMode()獲取mode
    MeasureSpec.getSize()獲取size
    MeasureSpec.makeMeasureSpec(size,mode)根據(jù)傳入的size和mode返回對應(yīng)的measureSpec

  • mode測量模式分為三類:
    (1)UNSPECIFIED:未指明大小,父視圖不約束子視圖
    (2)EXACTLY:明確大小,父視圖為子視圖明確指定一個(gè)確切的尺寸 使用match_parent或具體數(shù)值
    (3)AT_MOST:最大尺寸,父視圖為子視圖指定一個(gè)最大尺寸 wrap_content

2、onLayout 布局

作用:獲取四個(gè)頂點(diǎn),決定View的位置。

  • 布局過程
    布局過程也是自上而下,不同的是ViewGroup先調(diào)用onLayout讓自己布局,然后再讓子View布局,而onMeasure是先測量子View的大小再確定自身大小。
    (1).單視圖不需要實(shí)現(xiàn)該方法,視圖組需要實(shí)現(xiàn)onLayout()來對子view進(jìn)行布局
    (2).對于單視圖確定位置是在基類layout()中方法確定的,對于視圖組自身位置也是layout()方法確定。layout主要用來確定子view的位置
    (3).layout方法中確定位置的方法是setFrame和setOpticalFrame
    (4).在視圖組中,復(fù)寫onLayout方法。在其中遍歷子view,對于每個(gè)view依次調(diào)用layout->onLayout

3、onDraw 繪制

作用:顯示內(nèi)容

  • 繪制過程
    繪制背景、繪制內(nèi)容、繪制子view、繪制裝飾器
    draw -> drawBackground -> onDraw -> dispatchDraw -> onDrawScrollBars
    自定義View可重寫onDraw以繪制不同內(nèi)容

4、invalidate/postInvalidate/requestLayout

  • invalidate\postInvalidate
    作用:都是調(diào)用onDraw方法達(dá)到重新繪制的目的
    區(qū)別:invalidate只能在主線程中調(diào)用,postInvalidate能在子線程中調(diào)用,postInvalidate內(nèi)部使用了handler\message機(jī)制最終還是掉用invalidate方法。

  • requestLayout
    作用:調(diào)用onMeasure\onLayout重新測量和布局,有可能調(diào)用onDraw重新繪制。

5、ViewRoot/DecorView

  • ViewRoot(實(shí)際是ViewRootImpl):連接WindowManagerService和DecorView(最層級的View)的橋梁。View的三大流程均是通過ViewRootImpl來實(shí)現(xiàn)的。
  • DecorView:頂級View,本身是一個(gè)FrameLayout。分為標(biāo)題欄和內(nèi)容欄,內(nèi)容欄的id是R.android.id.content。Activity中的setContentView()方法最終是通過window.setContentView()
    添加到DecorView的內(nèi)容欄中。

6、View的繪制流程

  • View的繪制流程是從ViewRoot的performTraversals方法開始:
  • performTraversals會依次調(diào)用performMeasure\performLayout\performDraw,分別完成頂層View的測量、布局、繪制。
    過程中會對子View完成測量、布局、繪制。

7、getMeasuredHeight 和 getHeight 方法的區(qū)別(同理getMeasuredWith/getWith)

  • 1、getMeasuredWidth是在onMeasure之后,getWidth是在onLayout之后。
    2、getMeasuredHeight方法返回的是測量后View的高度,與屏幕無關(guān)。getHeight返回的是屏幕顯示的高度。當(dāng)View沒有超出屏幕時(shí),他們的值
    是相等的,但當(dāng)View超出屏幕顯示時(shí),getMeasuredHeight的值等于getHeight的值加上超出的高度。

  • 為什么有時(shí)候用getWidth()或者getMeasureWidth()得到0?
    View的繪制周期和Activity的生命周期不一致,所以在onCreate\onStart\onResume中調(diào)用方法都無法保證View測量、布局完成,所以獲取的結(jié)果為0.

相關(guān)資料文章:
Android 繪制原理淺析【干貨】

十三.多線程編程

1、為何有多線程?

  • 主線程(UI線程)
    • 在Android當(dāng)中, 當(dāng)應(yīng)用啟動的時(shí)候,系統(tǒng)會給應(yīng)用分配一個(gè)進(jìn)程,順便一提,大部分應(yīng)用都是單進(jìn)程的,不過也可以通過設(shè)置來使不同組件運(yùn)行在不同的進(jìn)程中,
      在創(chuàng)建進(jìn)程的同時(shí)會創(chuàng)建一個(gè)線程,應(yīng)用的大部分操作都會在這個(gè)線程中運(yùn)行。所以稱為主線程,同時(shí)所有的UI控件相關(guān)的操作也要求在這個(gè)線程中操作,所以也稱為UI線程。
  • 為何會有子線程
    • 因?yàn)樗械腢I控件的操作都在UI線程中執(zhí)行,如果在UI線程中執(zhí)行耗時(shí)操作,例如網(wǎng)絡(luò)請求等,就會阻塞UI線程,導(dǎo)致系統(tǒng)報(bào)ANR(Application Not Response)錯(cuò)誤。
      因此對于耗時(shí)操作需要?jiǎng)?chuàng)建工作線程來執(zhí)行而不能直接在UI線程中執(zhí)行。這樣就需要在應(yīng)用中使用多線程,但是Android提供的UI工具包并不是線程安全的,也就是說不能直接在
      工作線程中訪問UI控件,否則會導(dǎo)致不能預(yù)測的問題, 因此需要額外的機(jī)制來進(jìn)行線程交互,主要是讓其他線程可以訪問UI線程。

2、AsyncTask

  • 定義:輕量級的異步任務(wù)類,內(nèi)部封裝了線程池、handler

  • 缺點(diǎn):1、使用的是默認(rèn)的線程池
    2、與Activity的生命周期不一致,在執(zhí)行完doInBackground后才完結(jié)。
    3、容易造成內(nèi)存泄漏,AsyncTask持有Activity的引用。
    4、當(dāng)Activity生命周期異常后,AsyncTask結(jié)果丟失
    目前AsyncTask已被遺棄,推薦使用協(xié)程

3、ThreadPool

  • 線程池規(guī)則:

    • 當(dāng)線程池中的核心線程數(shù)未達(dá)到最大時(shí),啟動一個(gè)核心線程去執(zhí)行任務(wù)。
    • 如果核心線程數(shù)達(dá)到最大,任務(wù)會安排到任務(wù)隊(duì)列中等待。
    • 核心線程達(dá)到最大、任務(wù)隊(duì)列已滿,啟動一個(gè)非核心線程執(zhí)行任務(wù)。
    • 核心線程最大、任務(wù)隊(duì)列已滿、非核心線程達(dá)到最大,線程池拒絕執(zhí)行任務(wù)。
  • 優(yōu)點(diǎn):

    • 降低線程創(chuàng)建和銷毀的系統(tǒng)開銷
    • 線程復(fù)用,提高系統(tǒng)吞吐量
    • 執(zhí)行大量異步任務(wù)時(shí),提高性能
    • 提供了相關(guān)管理的API,使用方便
  • execute :
    service.execute(new Runnable() {
       public void run() {
           System.out.println("execute方式");
       }
    });
    
  • submit :
      Future<Integer> future = service.submit(new Callable<Integer>() {
      
          @Override
          public Integer call() throws Exception {
              System.out.println("submit方式");
              return 2;
          }
      });
      try {
          Integer number = future.get();
      } catch (ExecutionException e) {
          e.printStackTrace();
      }
    
  • 線程池關(guān)閉:
    • 調(diào)用線程池的shutdown()shutdownNow()方法來關(guān)閉線程池
    • shutdown原理:將線程池狀態(tài)設(shè)置成SHUTDOWN狀態(tài),然后中斷所有沒有正在執(zhí)行任務(wù)的線程。
    • shutdownNow原理:將線程池的狀態(tài)設(shè)置成STOP狀態(tài),然后中斷所有任務(wù)(包括正在執(zhí)行的)的線程,并返回等待執(zhí)行任務(wù)的列表。
    • 中斷采用interrupt方法,所以無法響應(yīng)中斷的任務(wù)可能永遠(yuǎn)無法終止。
      但調(diào)用上述的兩個(gè)關(guān)閉之一,isShutdown()方法返回值為true,當(dāng)所有任務(wù)都已關(guān)閉,表示線程池關(guān)閉完成,則isTerminated()方法返回值為true。
      當(dāng)需要立刻中斷所有的線程,不一定需要執(zhí)行完任務(wù),可直接調(diào)用shutdownNow()方法。

4、IntentService

  • 定義:可以在內(nèi)部開啟子線程執(zhí)行耗時(shí)任務(wù)的服務(wù)。

  • 原理:繼承至Service,內(nèi)部封裝了handler、looper、thread等用于子線程與主線程的交互。

5、TreadLocal

  • 定義:
    存儲一個(gè)數(shù)據(jù),對指定的線程可見。

  • 原理:
    通過使用當(dāng)前線程的TreadLocalMap對set(value)的value進(jìn)行存儲,key為當(dāng)前的TreadLocal。get()方法通過當(dāng)前TreadLocal為key,在當(dāng)前線程的TreadLocalMap中取值。

  • ThreadLocalMap
    在Tread類中有TreadLocalMap的成員變量。TreadLocalMap是一種存儲K-V的數(shù)據(jù)結(jié)構(gòu),內(nèi)部使用的是哈希表結(jié)構(gòu)。

6、java內(nèi)存分區(qū)和java內(nèi)存模型(JMM)

  • 內(nèi)存分區(qū):
    ·程序計(jì)數(shù)器
    ·本地方法區(qū)
    - 存儲與本地native方法交互的字節(jié)碼
    ·虛擬機(jī)棧
    - 內(nèi)部使用的 棧幀 結(jié)構(gòu):(1)局部變量表(2)操作數(shù)棧(3)動態(tài)連接(4)返回地址
    ·方法區(qū)
    - 存儲類信息、元數(shù)據(jù)、常量池
    ·堆
    - 存儲實(shí)例對象,GC作用的主要區(qū)域

  • JMM:
    規(guī)定所有的變量都存儲在主內(nèi)存中,每條線程還有自己的工作內(nèi)存。線程中的工作內(nèi)存保存了被線程使用的變量的主內(nèi)存副本,線程對變量的操作都必須在工作內(nèi)存中進(jìn)行,
    不能直接讀寫主內(nèi)存中的變量,不同線程之間也無法直接訪問對方工作內(nèi)存中的變量副本。線程間變量值的傳遞需要通過主內(nèi)存來完成。

7、volatile

  • 輕量級線程同步,保證操作數(shù)據(jù)的可見性、有序性,不保證原子性

8、synchronized

  • 修飾普通方法、靜態(tài)方法、代碼塊(this\object)

9、ReentrantLock

  • reentrantLock 可重入鎖
    對比Synchronized那有些區(qū)別和優(yōu)點(diǎn)?
    ·在語法上Synchronized是原生語法提供。在用法上可修飾方法、代碼塊。而reentrantLock需配合try-catch使用,并且需要手動釋放鎖。
    ·reentrantLock 等待可中斷,是樂觀鎖,而Synchronized是獨(dú)占鎖,悲觀鎖。
    ·reentrantLock 可以添加多個(gè)鎖條件
    ·reentrantLock 公平鎖,多個(gè)線程等待同一個(gè)鎖時(shí),必須按照申請鎖的時(shí)間順序獲得鎖。reentrantLock也可通過構(gòu)造方法設(shè)置為非公平鎖。

10、Atomic原子類

  • 定義:適用于單個(gè)元素,能夠保證一個(gè)基本數(shù)據(jù)類型、對象、或者數(shù)組的原子性。
    原子更新基本類型:AtomicInteger、AtomicBoolean、AtomicLong
    原子更新引用類型:AtomicReference、AtomicStampedReference、AtomicMarkableReference
    原子更新數(shù)組類型:AtomicLongArray、AtomicIntegerArray、AtomicReferenceArray
    原子更新對象屬性:AtomicIntegerFieldUpdater、AtomicLongFieldUpdater、AtomicReferenceFieldUpdater
  • 實(shí)現(xiàn)原理:
    • CAS(compare and swap):比較并交換 compareAndSwap(v,n,e)

相關(guān)資料文章:
ThreadLocal原理其實(shí)很簡單
Java并發(fā)包中的Atomic原子類

十四.跨進(jìn)程通信(IPC inter-process communication)

  • linux系統(tǒng)中使用到的IPC機(jī)制有:管道、共享內(nèi)存、socket、binder(android)等。

1、Binder機(jī)制

  • Android系統(tǒng)為什么要選用Binder機(jī)制作為進(jìn)程通信?
    答:
    ·binder數(shù)據(jù)傳遞只需要拷貝一次,效率較高
    ·安全性能高,通過給應(yīng)用分配UID來鑒別應(yīng)用的身份
    Android中的binder機(jī)制是一種高效率、安全性能高的進(jìn)程通信方式

  • 實(shí)現(xiàn)原理:
    · 進(jìn)程隔離:系統(tǒng)為確保自身的安全穩(wěn)定,將系統(tǒng)內(nèi)核空間和用戶空間分離開來。用戶空間的進(jìn)程要進(jìn)行交互需要通過內(nèi)核空間來驅(qū)動整個(gè)過程。
    · C/S結(jié)構(gòu):Binder作為一個(gè)Service的實(shí)體,對象提供一系列的方法來實(shí)現(xiàn)服務(wù)端和客戶端之間的請求,只要client拿到這個(gè)引用就可以進(jìn)行通信。
    (binder對象是一個(gè)可以跨進(jìn)程引用的對象,它的實(shí)體位于一個(gè)進(jìn)程中,而它的引用卻遍布系統(tǒng)的各個(gè)進(jìn)程中)
    · 通信模型:
    · Server : 跨進(jìn)程服務(wù)端,運(yùn)行在某個(gè)進(jìn)程,通過Binder驅(qū)動在ServiceManager中注冊
    · Client : 跨進(jìn)程客戶端,運(yùn)行在某個(gè)進(jìn)程,通過Binder驅(qū)動獲取ServiceManager中的服務(wù)
    · ServiceManager : 提供服務(wù)的注冊和查詢,運(yùn)行在SystemServer進(jìn)程
    · Binder驅(qū)動:前三者位于用戶空間,binder驅(qū)動位于內(nèi)核空間,其實(shí)現(xiàn)方式和驅(qū)動差不多,負(fù)責(zé)進(jìn)程之間Binder通信的建立,Binder在進(jìn)程中的傳遞,Binder引用計(jì)數(shù)管理,
    數(shù)據(jù)包在進(jìn)程之間的傳遞和交互。
    · 內(nèi)存映射:Memory Map,將用戶空間的一塊內(nèi)存地址映射到內(nèi)核空間,映射關(guān)系建立后,用戶對這塊內(nèi)存的修改可以直接反應(yīng)到內(nèi)核空間中。
    減少了數(shù)據(jù)拷貝的次數(shù),實(shí)現(xiàn)用戶空間和內(nèi)核空間的高效互動。

    (1)Binder驅(qū)動在內(nèi)核空間中創(chuàng)建了一個(gè)數(shù)據(jù)接收緩存區(qū)
    (2)并在內(nèi)核空間開辟了一個(gè)內(nèi)核緩存區(qū),建立內(nèi)核緩存區(qū)和數(shù)據(jù)接收緩存區(qū)的映射關(guān)系,以及數(shù)據(jù)接收緩存區(qū)和用戶空間地址的映射關(guān)系。
    (3)發(fā)送方進(jìn)程通過copy_to_user函數(shù)將數(shù)據(jù)發(fā)送到內(nèi)核緩存區(qū),由于內(nèi)核緩存區(qū)與數(shù)據(jù)接收區(qū)存在映射,而數(shù)據(jù)接收緩存區(qū)和用戶空間地址映射,所以相當(dāng)于把數(shù)據(jù)發(fā)送到
    接收方的用戶空間。

2、AIDL(android interface definition language) Android接口定義語言

  • 定義:Android接口定義語言,是一套模板代碼,讓某個(gè)service與多個(gè)應(yīng)用程序組件之間跨進(jìn)程通信。

相關(guān)資料文章:
Android Binder原理(一)

十五.圖片相關(guān)(bitmap加載、處理、緩存)

1、Bitmap加載(本地、網(wǎng)絡(luò))

  • 原生方法加載網(wǎng)絡(luò)圖片
 private Bitmap returnBitmapFormUrl(String url) {
        long l1 = System.currentTimeMillis();
        Bitmap bitmap = null;
        HttpURLConnection connection = null;
        InputStream inputStream = null;
        URL myUrl = null;
        try {
            myUrl = new URL(url);
            connection = (HttpURLConnection) myUrl.openConnection();
            connection.setReadTimeout(6000);
            connection.setConnectTimeout(6000);
            connection.setDoInput(true);
            connection.connect();
            inputStream = connection.getInputStream();
            bitmap = BitmapFactory.decodeStream(inputStream);
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if(inputStream != null){
                try {
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            l1 = System.currentTimeMillis();
        }
        return bitmap;
    }
  • 使用三方插件Glide

2、Bitmap處理(保存、壓縮)

  • 保存圖片至相冊
private void saveImageToFile(Context context, Bitmap bitmap) {
        File appDir = new File(Environment.getExternalStorageState(), "test");
        if (!appDir.exists()) {
            appDir.mkdir();
        }
        String fileName = System.currentTimeMillis() + ".jpg";
        File file = new File(appDir, fileName);
        try {
            FileOutputStream fos = new FileOutputStream(file);
            bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos);
            fos.flush();
            fos.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        try {
            MediaStore.Images.Media.insertImage(context.getContentResolver(), file.getAbsolutePath(), fileName, null);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        Intent intent = new Intent();
        intent.setAction(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
        intent.setData(Uri.parse("file://"+file.getAbsolutePath()));
        context.sendBroadcast(intent);
    }
  • 圖片壓縮
    • Bitmap.compress() 質(zhì)量壓縮,不會對內(nèi)存產(chǎn)生影響
    • BitmapFactory.Options.inSampleSize 內(nèi)存壓縮

3、大圖加載

  • BitmapFactory.decodeStream(): 獲取圖片

  • BitmapFactory.Option(): 設(shè)置圖片相關(guān)參數(shù)(設(shè)置顯示大小、縮放比例等)
    option.inSimpleSize = 2

  • BitmapRegionDecoder: 圖片局部展示

4、圖片緩存

  • LurCache
    內(nèi)部采用LinkedHashMap存儲數(shù)據(jù),其最重要的方法trimToSize是用來移除最少使用的緩存和使用最久的緩存,并添加最新的緩存到隊(duì)列中。

5、圖片占用內(nèi)存

  • getByteCount/getAllocationByteCount

  • with * height * 單個(gè)像素內(nèi)存大小

6、如何避免加載圖片出現(xiàn)OOM?

  • 加載圖片前,獲取圖片占用內(nèi)存大小,決定是否壓縮
  • 對比源圖片寬高和控件寬高,決定是否縮放 BitmapFactory.Options的inJustDecodeBounds屬性設(shè)置為true,解析一次圖片獲取圖片寬高
  • 采用局部加載BitmapRegionDecoder
  • 多張圖片的采用弱引用
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,967評論 6 531
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,273評論 3 415
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,870評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,742評論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 71,527評論 6 407
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,010評論 1 322
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,108評論 3 440
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,250評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 48,769評論 1 333
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 40,656評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 42,853評論 1 369
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,371評論 5 358
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,103評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,472評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,717評論 1 281
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 51,487評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 47,815評論 2 372