Android之AsyncTask異步任務(wù)

1? ? ? AsyncTask異步任務(wù)

1.1????ANR的概念

Application Not Responding,應(yīng)用程序無響應(yīng)

Android系統(tǒng)規(guī)定只有UI線程(主線程)能夠修改UI界面,但是如果在UI線程中執(zhí)行耗時操作,則會導(dǎo)致線程阻塞,影響用戶體驗,如果耗時操作導(dǎo)致阻塞時間過長,則有可能會引起系統(tǒng)ANR

產(chǎn)生的原因

用戶在界面上的操作是由主線程處理,如果主線程被阻塞,那么就沒有辦法響應(yīng)用戶的操作,這時候可以看做是程序就“卡住了”,如果阻塞超過5秒,就會導(dǎo)致ANR。

如何避免ANR?

我們只需要將會造成主線程阻塞的操作(耗時操作)放在子線程中就可以了。

注意事項

1、超過5秒沒有響應(yīng)用戶操作才會導(dǎo)致ANR,那么是不是5秒之內(nèi)的耗時操作就可以在主線程中執(zhí)行?

不是的,即使沒有導(dǎo)致ANR也會影響用戶的體驗,一般200ms以上的操作都屬于耗時操作應(yīng)該放在子線程中執(zhí)行

1、? ANR的產(chǎn)生不只是因為主線程被阻塞,根本的原因是程序沒有響應(yīng)用戶的操作超過5秒,才會導(dǎo)致ANR。

但是,Android系統(tǒng)規(guī)定,和界面UI更新相關(guān)的操作必須在主線程中執(zhí)行,如果在子線程中對UI界面進(jìn)行更新操作,就會拋出異常,導(dǎo)致程序奔潰。

異常信息:android.view.ViewRootImpl$CalledFromWrongThreadException: Only theoriginal thread that created a view hierarchy can touch its views.

問題:執(zhí)行耗時操作需要在子線程中完成,但是子線程不能更新UI,怎么辦?

答:Android提供了消息機(jī)制可能解決這個問題,原理就是子線程中如果需要更新UI,就“通知”主線程更新UI

Android提供了以下方式解決上面的問題:

1、Handler消息機(jī)制(后面講)

2、AsyncTask異步任務(wù)

1.2????Android系統(tǒng)中線程的概念

MainThread 主線程(UI線程):應(yīng)用啟動時創(chuàng)建,處理與UI相關(guān)事情,如點擊事件、數(shù)據(jù)更新

WorkThread 子線程(工作線程):Android 4.0之后UI線程不能訪問網(wǎng)絡(luò)資源或執(zhí)行耗時操作,必須開啟子線程

1.3????AsyncTask類的基本使用

Android提供的異步任務(wù)類,主要作用是可以在子線程中執(zhí)行耗時操作,并通知主線程更新UI

功能

在類中實現(xiàn)異步操作,并提供回調(diào)方法反饋當(dāng)前異步執(zhí)行的程度,最后將反饋的結(jié)果提供給UI主線程

回調(diào)方法

1.onPreExecute: 線程任務(wù)開始執(zhí)行前的準(zhǔn)備工作(運行在線程中)

2.doInBackground:在線程中執(zhí)行耗時操作, 在線程中執(zhí)行的代碼(后臺開啟了線程并執(zhí)行這部分代碼)

3.onProgressUpdate: 在線程的執(zhí)行中需要執(zhí)行的界面操作(運行在線程中)

4.onPostExecute:在子線程直線完畢之后調(diào)用(在線程中執(zhí)行)

其它回調(diào)方法:

5.onCancelled()是當(dāng)調(diào)用cancel方法取消任務(wù)并doInBackground執(zhí)行完之后才會調(diào)用

常用方法

execute:執(zhí)行任務(wù)

cancel(boolean):取消任務(wù)

isCancelled():判斷當(dāng)前任務(wù)是否被取消

publishProgress(int progressValue):發(fā)布任務(wù)進(jìn)度

三個泛型參數(shù)

第一個泛型參數(shù):(定義)是傳遞給doInBackground方法的參數(shù)的類型(引用類型),由execute(…..)方法初傳入

第二個泛型參數(shù):(定義)是傳遞給onProgressUpdate方法的參數(shù)的類型,由publishProgress(。。。。。)方法傳入

第三個泛型參數(shù):是傳遞給onPostExecute方法的參數(shù)的類型,接收的是doInBackground方法的返回值

基本使用步驟

1、定義一個類,繼承自AsyncTask,并指定三個泛型

2、重寫回調(diào)方法

3、在UI線程中實例化AsyncTask對象

4、在UI線程中,執(zhí)行AsyncTask對象的execute(..)方法,開始執(zhí)行異步任務(wù)

5、在執(zhí)行過程中,可以通過調(diào)用cancel(true)方法,停止異步任務(wù)

使用AsyncTask必須遵守的準(zhǔn)則

三個泛型使用位置

第一個泛型:在doInBackground()方法中使用

第二個泛型:在onProgressUpdate()方法中使用

第三個泛型:在onPostExecute()方法中使用

AsyncTask的實例必須在UIthread中創(chuàng)建

execute方法必須在UI線程中被調(diào)用

一個AsyncTask實例只能被執(zhí)行一次,否則多次調(diào)用時將會出現(xiàn)異常

1.4????Guithub開源框架簡介

MarkdownPad?--:用于看.md文件格式的文檔工具。

Volley、XUtils、Universal-Image-Loader、okhttp、SlidingMenu、android-async-http、fresco

ButterKnife、EventBus

1.4.1? 運用xutils框架下載圖片

publicclassMainActivityextendsActivity {

@ViewInject(R.id.iv)ImageViewiv;

@Override

protectedvoidonCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

}

publicvoiddownloadImage(View v){

//下載圖片

HttpUtilshttpUtils =newHttpUtils();

Stringurl ="http://api.k780.com:88/?app=weather.future&weaid=1&&appkey=10003&sign=b59bc3ef6191eb9f747dd4e83c99f2a4&format=json";

httpUtils.send(HttpMethod.GET, url,newRequestCallBack() {

@Override

publicvoidonFailure(HttpException arg0, String arg1) {

}

@Override

publicvoidonSuccess(ResponseInfo arg0) {

Toast.makeText(MainActivity.this, arg0.result,0).show();

}

});

}

}

1.5????拓展

當(dāng)有多個異步任務(wù)被同時啟動時,那么是多個同時執(zhí)行還是依次排隊執(zhí)行??

當(dāng)有多個異步任務(wù)通過execute方法被同時啟動時,是依次排隊執(zhí)行的,即

只有當(dāng)?shù)谝粋€啟動被啟動的異步任務(wù)執(zhí)行完畢后才會去執(zhí)行下一個

如何實現(xiàn)讓多條異步任務(wù)同時執(zhí)行??

1.當(dāng)多個異步對象通過execute方法啟動時,

* 特點:不管異步任務(wù)對象是否屬于同類別,使用都保持依次排隊執(zhí)行的特點

2. 如果需要讓多個異步任務(wù)同時執(zhí)行的話,可以選擇使用

*executeOnExecutor方法啟動異步任務(wù)

* 參數(shù):

* 1:Executor線程池對象,可以通過此對象指定同時可以有多少個異步任務(wù)一起運行

* 2:作用與execute方法中的參數(shù)作用完全一致

* 注意:此處的數(shù)字不要添加的太多,否則影響速度

指定同時執(zhí)行3條異步任務(wù),代碼如:

Executorexec= Executors.newFixedThreadPool(3);

newMyTask().executeOnExecutor(exec,pb);

newMyTask().executeOnExecutor(exec,pb2);

newMyTask().executeOnExecutor(exec,pb3);

1.5.1? 示例多個異步同時執(zhí)行

publicclassMainActivityextendsActivity {

privateProgressBarpb,pb2,pb3;

@Override

protectedvoidonCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

//初始化控件

initView();

}

privatevoidinitView() {

pb= (ProgressBar)this.findViewById(R.id.progressBar1);

pb2= (ProgressBar)this.findViewById(R.id.progressBar2);

pb3= (ProgressBar)this.findViewById(R.id.progressBar3);

}

publicvoidbtnClick(View v){

Executor exec = Executors.newFixedThreadPool(3);//同時執(zhí)行的線程數(shù)

new MyTask().executeOnExecutor(exec,pb);

new MyTask().executeOnExecutor(exec,pb2);

new MyTask().executeOnExecutor(exec,pb3);

}

//異步任務(wù)

classMyTaskextendsAsyncTask{

ProgressBarcurrentPb;

@Override

protectedVoid doInBackground(ProgressBar...params) {

//TODOAuto-generated method stub

currentPb= params[0];

for(inti=0;i<=100;i++){

try{

Thread.sleep(100);

publishProgress(i);

}catch(InterruptedException e) {

//TODOAuto-generated catch block

e.printStackTrace();

}

}

returnnull;

}

@Override

protectedvoidonProgressUpdate(Integer... values) {

//TODOAuto-generated method stub

super.onProgressUpdate(values);

currentPb.setProgress(values[0]);

}

}

}

1.5.2? 同時異步多圖片下載

publicclassTwoActivityextendsActivity {

/*

*實現(xiàn)多張圖片同時下載并且在圖片下載過程中時刻顯示圖片的下載進(jìn)度

*/

ImageViewiv,iv2,iv3;

ProgressBarpb,pb2,pb3;

String[]urls= {

"https://ss0.bdstatic.com/5aV1bjqh_Q23odCf/static/superman/img/logo/bd_logo1_31bdc765.png",

"https://ss0.bdstatic.com/5aV1bjqh_Q23odCf/static/superman/img/logo/bd_logo1_31bdc765.png",

"https://ss0.bdstatic.com/5aV1bjqh_Q23odCf/static/superman/img/logo/bd_logo1_31bdc765.png"};

@Override

protectedvoidonCreate(Bundle savedInstanceState) {

//TODOAuto-generated method stub

super.onCreate(savedInstanceState);

setContentView(R.layout.two);

initView();

}

privatevoidinitView() {

iv= (ImageView) findViewById(R.id.imageView1);

iv2= (ImageView) findViewById(R.id.imageView2);

iv3= (ImageView) findViewById(R.id.imageView3);

pb= (ProgressBar) findViewById(R.id.progressBar1);

pb2= (ProgressBar) findViewById(R.id.progressBar2);

pb3= (ProgressBar) findViewById(R.id.progressBar3);

}

publicvoidclick(View v) {

Executor exec = Executors.newFixedThreadPool(2);

newImageTask().executeOnExecutor(exec,urls[0],iv,pb);

newImageTask().executeOnExecutor(exec,urls[1],iv2,pb2);

newImageTask().executeOnExecutor(exec,urls[2],iv3,pb3);

}

classImageTaskextendsAsyncTask {

ImageViewcurrentIv;

ProgressBarcurrentPb;

@Override

protectedBitmap doInBackground(Object...params) {

//TODOAuto-generated method stub

Stringurl = (String) params[0];

currentIv= (ImageView) params[1];

currentPb= (ProgressBar) params[2];

try{

HttpURLConnectionconn = (HttpURLConnection)newURL(url)

.openConnection();

conn.setRequestMethod("GET");

conn.connect();

if(conn.getResponseCode() == 200) {

InputStreamis = conn.getInputStream();

byte[] b =newbyte[1024];

intnum = -1;

ByteArrayOutputStreambos =newByteArrayOutputStream();

intcurrent = 0;

inttotal = conn.getContentLength();

while((num = is.read(b)) != -1) {

bos.write(b,0, num);

SystemClock.sleep(100);

current+= num;

publishProgress(total, current);

}

byte[]bitm = bos.toByteArray();

returnBitmapFactory.decodeByteArray(bitm,0, bitm.length);

}

}catch(MalformedURLException e) {

//TODOAuto-generated catch block

e.printStackTrace();

}catch(IOException e) {

//TODOAuto-generated catch block

e.printStackTrace();

}

returnnull;

}

@Override

protectedvoidonProgressUpdate(Integer... values) {

//TODOAuto-generated method stub

super.onProgressUpdate(values);

currentPb.setMax(values[0]);

currentPb.setProgress(values[1]);

}

@Override

protectedvoidonPostExecute(Bitmap result) {

//TODOAuto-generated method stub

super.onPostExecute(result);

if(result !=null){

currentIv.setImageBitmap(result);

}

}

}

}

1.6????案例

1.6.1? ? 案例:簡易計時器

publicclassMainActivityextendsActivity {

privateTextViewtv_count;

privateintcount= 0;

privateCountTaskcountTask;

@Override

protectedvoidonCreate(BundlesavedInstanceState){

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

tv_count= (TextView)this.findViewById(R.id.tv_count);

}

//開始計數(shù)

publicvoidstartCount(View v) {

if(countTask==null) {

countTask=newCountTask();

countTask.execute();

}

}

//暫停

publicvoidpauseCount(View v) {

if(countTask!=null) {

countTask.cancel(true);

countTask=null;

}

}

//重置

publicvoidreset(View v) {

pauseCount(null);

count= 0;

tv_count.setText("00:00:00");

}

//開啟異步任務(wù)

privateclassCountTaskextendsAsyncTask {

@Override

protectedVoid doInBackground(Void... params){

while(!isCancelled()) {

try{

Thread.sleep(10);

//通知主線程更新顯示

publishProgress(++count);

}catch(InterruptedException e) {

//TODOAuto-generated catch block

e.printStackTrace();

break;

}

}

returnnull;

}

@Override

protectedvoidonProgressUpdate(Integer... values) {

if(isCancelled()) {

return;

}

intss = values[0];

intmm = values[0] / 60;

inthh = values[0] / 60 / 60;

// tv_count.setText(values[0]+"");

tv_count.setText(hh +":"+ mm +":"+ ss);

}

//當(dāng)子線程成功執(zhí)行之后調(diào)用

@Override

protectedvoidonPostExecute(Void result) {

Log.i("mtag","onPostExecute");

Toast.makeText(MainActivity.this,"onPostExecute",0).show();

}

//當(dāng)被中斷取消時調(diào)用

@Override

protectedvoidonCancelled() {

Log.i("mtag","onCancelled");

}

}

}

1.6.2? ? 案例:下載一張圖片

Android4.0開始,Android系統(tǒng)規(guī)定不能在UI線程中執(zhí)行訪問網(wǎng)絡(luò)資源的操作,相關(guān)操作必須在子線程中完成

Android網(wǎng)絡(luò)訪問需要的權(quán)限:android.permission.INTERNET

/**

* 網(wǎng)絡(luò)訪問工具類

*

*@authorEvanYu

*@date2016.01.08

*/

publicclassHttpUtils {

/**

* 網(wǎng)絡(luò)訪問超時時間

*/

publicstaticfinalintTIMEOUT= 10000;

/**

* 通過get方式實現(xiàn)網(wǎng)絡(luò)請求

*

*@paramurl

*???????????訪問的url地址

*@return請求的結(jié)果,null代表請求失敗

*/

publicstaticbyte[] doGet(String url) {

HttpURLConnection conn =null;

try{

URL mUrl =newURL(url);

conn = (HttpURLConnection)mUrl.openConnection();

conn.setRequestMethod("GET");

conn.setConnectTimeout(TIMEOUT);

conn.setReadTimeout(TIMEOUT);

conn.connect();

intcode= conn.getResponseCode();

if(code== 200) {

returnreadStream(conn.getInputStream());

}else{

thrownewRuntimeException("網(wǎng)絡(luò)訪問失?。?+ code);

}

}catch(Exception e) {

e.printStackTrace();

returnnull;

}finally{

if(conn!=null) {

conn.disconnect();

conn =null;

}

}

}

publicstaticbyte[] doPost(String url, String params) {

HttpURLConnection conn =null;

try{

URL mUrl =newURL(url);

conn = (HttpURLConnection)mUrl.openConnection();

conn.setRequestMethod("POST");

conn.setConnectTimeout(TIMEOUT);

conn.setReadTimeout(TIMEOUT);

//設(shè)置請求屬性

conn.setRequestProperty("Content-Type",

"application/x-www-form-urlencoded");

conn.setRequestProperty("Content-Length", params.length() +"");

// Post請求必須要寫以下兩行代碼

conn.setDoInput(true);

conn.setDoOutput(true);

//將請求參數(shù)寫到請求體中

conn.getOutputStream().write(params.getBytes());

;

conn.connect();

intcode= conn.getResponseCode();

if(code== 200) {

returnreadStream(conn.getInputStream());

}else{

thrownewRuntimeException("網(wǎng)絡(luò)訪問失?。?+ code);

}

}catch(Exception e) {

e.printStackTrace();

returnnull;

}finally{

if(conn!=null) {

conn.disconnect();

conn =null;

}

}

}

privatestaticbyte[] readStream(InputStream is)throwsIOException {

ByteArrayOutputStream baos =newByteArrayOutputStream();

byte[] buf =newbyte[1024];

intlen = 0;

while((len = is.read(buf)) != -1) {

baos.write(buf, 0, len);

}

returnbaos.toByteArray();

}

}

1.6.3? ? 案例:下載文件時顯示進(jìn)度

使用ProgressBar控件顯示下載進(jìn)度

使用ProgressDialog顯示下載進(jìn)度

構(gòu)造方法:ProgressDialog(Contextcontext)

設(shè)置進(jìn)度條樣式:setProgressStyle(intstyle)

設(shè)置標(biāo)題:setTitle(CharSequence)

設(shè)置標(biāo)題圖標(biāo):setIcon(intresId)

設(shè)置顯示內(nèi)容:setMessage(CharSequencemessage)

設(shè)置進(jìn)度值:setProgress(intvalue)

顯示對話框:show()

關(guān)閉對話框:cancel()

publicclassMainActivityextendsActivity {

privateImageViewimg_view;

@Override

protectedvoidonCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

img_view= (ImageView)this.findViewById(R.id.img_view);

}

publicvoiddownloadImg(View v) {

// Stringurl=

//"https://ss0.bdstatic.com/5aV1bjqh_Q23odCf/static/superman/img/logo/bd_logo1_31bdc765.png";

Stringurl ="http://img1.imgtn.bdimg.com/it/u=335355609,381250936&fm=21&gp=0.jpg";

newMyAsynTask().execute(url);

}

privateclassMyAsynTaskextendsAsyncTask {

ProgressDialog pDialog;

@Override

protectedvoidonPreExecute() {

//開始下載之前先顯示一個對話框

pDialog=newProgressDialog(MainActivity.this);

pDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);

pDialog.setMax(100);

pDialog.setTitle("下載圖片");

pDialog.setMessage("正在下載圖片.....");

pDialog.show();

}

@Override

protectedBitmap doInBackground(String...params) {

/*

* Stringurl=params[0]; byte[]data = HttpUtils.doGet(url);

* //將下載到的數(shù)據(jù)解析成一張圖片Bitmapbm=BitmapFactory.decodeByteArray(data,

* 0, data.length); SystemClock.sleep(2000);returnbm;

*/

HttpURLConnectionconn =null;

try{

Stringurl = params[0];

URLmurl =newURL(url);

conn= (HttpURLConnection) murl.openConnection();

conn.setRequestMethod("GET");

intcode = conn.getResponseCode();

if(code == 200) {

//獲取數(shù)據(jù)的總大小

inttatalSize = conn.getContentLength();

floatcurSize = 0;//記錄當(dāng)前已經(jīng)下載的大小

InputStreamis = conn.getInputStream();

ByteArrayOutputStreambaos =newByteArrayOutputStream();

byte[] buf =newbyte[10];

intlength = 0;

while((length = is.read(buf)) != -1) {

baos.write(buf,0, length);

curSize+= length;

publishProgress((int) ((curSize / tatalSize) * 100));

//模擬耗時操作

SystemClock.sleep(20);

}

//將下載到的數(shù)據(jù)解析成一張圖片

byte[]data = baos.toByteArray();

Bitmapbm = BitmapFactory.decodeByteArray(data, 0,

data.length);

returnbm;

}else{

thrownewRuntimeException("網(wǎng)路訪問失敗"+ code);

}

}catch(Exception e) {

e.printStackTrace();

}finally{

if(conn !=null){

conn.disconnect();

conn=null;

}

}

returnnull;

}

@Override

protectedvoidonProgressUpdate(Integer... values) {

pDialog.setProgress(values[0]);

}

@Override

protectedvoidonPostExecute(Bitmap result) {

img_view.setImageBitmap(result);

//取消顯示

// pDialog.dismiss();

pDialog.cancel();

}

}

}

1.6.4? ? 案例:下載并顯示天氣信息

數(shù)據(jù)網(wǎng):K780數(shù)據(jù)網(wǎng)、聚合數(shù)據(jù)等

K780測試賬號

Appkey:15250

Secret:2bbebb3e480a850df6daca0c04a954e1

Sign:f88a5cecc3cbd37129bc090c0ae29943

網(wǎng)絡(luò)訪問工具類的封裝

HttpUtils類

K780數(shù)據(jù)訪問工具類的封裝

K780Utils類

public classWeather {

privateStringdays;

privateStringtemperature;

publicWeather() {

}

publicWeather(String day, String temperature) {

this.days= day;

this.temperature= temperature;

}

publicString getDay() {

returndays;

}

public voidsetDay(String day) {

this.days= day;

}

publicString getTemperature() {

returntemperature;

}

public voidsetTemperature(String temperature) {

this.temperature= temperature;

}

@Override

publicString toString() {

return"Weather[day="+days+", temperature="+temperature+"]";

}

}

引入網(wǎng)絡(luò)訪問工具類

publicclassMainActivityextendsActivity {

privateTextViewtv_show;

@Override

protectedvoidonCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

tv_show= (TextView) findViewById(R.id.tv_show);

}

publicvoiddownload(View v) {

Stringurl ="http://api.k780.com:88/?app=weather.future&weaid=1&&appkey=15250&sign=f88a5cecc3cbd37129bc090c0ae29943&format=json";

newMyTask().execute(url);

}

privateclassMyTaskextendsAsyncTask> {

@Override

protectedListdoInBackground(String... params) {

Stringdata;

try{

Listlist =newArrayList();

data=newString(HttpUtils.doGet(params[0]));

JSONObjectjsonObject =newJSONObject(data);

JSONArrayresult = jsonObject.getJSONArray("result");

for(inti = 0; i < result.length(); i++) {

JSONObjecttemp = result.getJSONObject(i);

Stringdays = temp.getString("days");

Stringtemperature = temp.getString("temperature");

list.add(newWeather(days, temperature));

}

returnlist;

}catch(JSONException e) {

//TODOAuto-generated catch block

e.printStackTrace();

}

returnnull;

}

@Override

protectedvoidonPostExecute(List result) {

// tv_show.setText(result);

for(Weather weather : result) {

tv_show.append(weather.toString() +"\n");

}

}

}

}

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

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