要點(diǎn)提煉|開發(fā)藝術(shù)之線程

本篇的主要內(nèi)容是Android的線程和線程池:

  • 概述
  • 線程形態(tài)
    • AsyncTask
    • HandlerThread
    • IntentService
  • 線程池

一.概述

1.含義:線程是CPU調(diào)度的最小單元。

2.特點(diǎn):線程是一種受限的系統(tǒng)資源。即線程不可無限制的產(chǎn)生且線程的創(chuàng)建和銷毀都有一定的開銷欣舵。

Q:如何避免頻繁創(chuàng)建和銷毀線程所帶來的系統(tǒng)開銷耳峦?
A:采用線程池,池中會(huì)緩存一定數(shù)量的線程,進(jìn)而達(dá)到效果。

3.分類:

  • 按用途可分為兩類:
    • 主線程:一般一個(gè)進(jìn)程只有一個(gè)主線程,主要處理界面交互相關(guān)的邏輯左权。
    • 子線程:除主線程之外都是子線程,主要用于執(zhí)行耗時(shí)操作痴颊。
  • 按形態(tài)可分為三類:
    • AsyncTask:底層封裝了線程池和Handler赏迟,便于執(zhí)行后臺(tái)任務(wù)以及在主線程中進(jìn)行UI操作。
    • HandlerThread:一種具有消息循環(huán)的線程蠢棱,其內(nèi)部可使用Handler锌杀。
    • IntentService:是一種異步甩栈、會(huì)自動(dòng)停止的服務(wù),內(nèi)部采用HandlerThread糕再。

二.線程形態(tài)

對(duì)于主線程和子線程相信已經(jīng)非常熟悉了量没,現(xiàn)在主要學(xué)習(xí)以下三種形態(tài)的線程:

1.AsyncTask

a.AsyncTask:一種輕量級(jí)的異步任務(wù)類。

在Android中實(shí)現(xiàn)異步任務(wù)機(jī)制有兩種方式:Handler和AsyncTask突想。

  • Handler機(jī)制存在的問題:代碼相對(duì)臃腫殴蹄;多任務(wù)同時(shí)執(zhí)行時(shí)不易精確控制線程。
  • 引入AsyncTask的好處:創(chuàng)建異步任務(wù)更簡(jiǎn)單猾担,直接繼承它可方便實(shí)現(xiàn)后臺(tái)異步任務(wù)的執(zhí)行和進(jìn)度的回調(diào)更新UI袭灯,而無需編寫任務(wù)線程和Handler實(shí)例就能完成相同的任務(wù)。

b.AsyncTask是抽象的泛型類绑嘹,其組成成員有:

  • 三個(gè)泛型參數(shù):
    • Params:表示執(zhí)行AsyncTask需要傳入的參數(shù)稽荧,可用于在后臺(tái)任務(wù)中使用;
    • Progress:表示后臺(tái)任務(wù)執(zhí)行的進(jìn)度圾叼;
    • Result: 表示后臺(tái)任務(wù)的返回結(jié)果的類型蛤克;
    • 若沒有傳遞具體的參數(shù)捺癞,這三個(gè)泛型參數(shù)都可使用void夷蚊。如:
//含義:在執(zhí)行AsyncTask時(shí)不需要傳入?yún)?shù)給后臺(tái)任務(wù)、使用整型數(shù)據(jù)來作為進(jìn)度顯示單位髓介,最后使用布爾型數(shù)據(jù)來反饋執(zhí)行結(jié)果
public abstract class AsyncTask<Void, Integer, Boolean>
  • 五個(gè)核心方法:
    • onPreExecute()
      • 運(yùn)行在:主線程
      • 調(diào)用時(shí)刻:在異步任務(wù)執(zhí)行之前被調(diào)用
      • 作用:可用于進(jìn)行一些界面上的初始化操作
    • doInBackground(Params…params)
      • 運(yùn)行在:子線程
      • 作用:可用于處理所有的耗時(shí)任務(wù)惕鼓。若需要更新UI需調(diào)用 publishProgress(Progress...)方法
      • 注意:任務(wù)一旦完成就通過return語句將任務(wù)的執(zhí)行結(jié)果返回,若Result被指定為void唐础,就可不返回執(zhí)行結(jié)果
    • onProgressUpdate(Progress…values)
      • 運(yùn)行在:主線程
      • 調(diào)用時(shí)刻:在后臺(tái)任務(wù)中調(diào)用publishProgress(Progress...)之后該方法會(huì)被調(diào)用
      • 作用:可利用方法中攜帶的參數(shù)如Progress來對(duì)UI進(jìn)行相應(yīng)地更新
    • onPostExecute(Result result)
      • 運(yùn)行在:主線程
      • 調(diào)用時(shí)刻:在異步任務(wù)執(zhí)行完畢并通過return語句返回時(shí)被調(diào)用
      • 作用:可利用方法中返回的數(shù)據(jù)來進(jìn)行一些UI操作
    • onCancelled()
      • 運(yùn)行在:主線程
      • 調(diào)用時(shí)刻:當(dāng)異步任務(wù)被取消時(shí)被調(diào)用
      • 作用:可用于做界面取消的更新
    • 注意:
      • 不要直接調(diào)用onPreExecute()箱歧、doInBackground()、onProgressUpdate()一膨、onPostExecute)和onCancelled()方法
      • AsyncTask對(duì)象必須在主線程創(chuàng)建
  • 開始和結(jié)束異步任務(wù)的方法:
    • execute(Params...params)
      • 必須在主線程中調(diào)用
      • 作用:表示開始一個(gè)異步任務(wù)
      • 注意:一個(gè)異步對(duì)象只能調(diào)用一次execute()方法
    • cancel(booleanmayInterruptIfRunning)
      • 必須在主線程中調(diào)用
      • 作用:表示停止一個(gè)異步任務(wù)

比如自定義一個(gè)AsyncTask呀邢,來模擬一個(gè)下載任務(wù):

class DownloadTask extends AsyncTask<Void, Integer, Boolean> {  
  
    @Override//初始化一個(gè)ProgressDialog  
    protected void onPreExecute() {  
        progressDialog.show();  
    }  
  
    @Override//具體的下載邏輯
    protected Boolean doInBackground(Void... params) {  
        try {  
            while (true) {  
                int downloadPercent = doDownload();  
                publishProgress(downloadPercent);  
                if (downloadPercent >= 100) {  
                    break;  
                }  
            }  
        } catch (Exception e) {  
            return false;  
        }  
        return true;  
    }  
  
    @Override//顯示當(dāng)前的下載進(jìn)度
    protected void onProgressUpdate(Integer... values) {  
        progressDialog.setMessage("當(dāng)前下載進(jìn)度:" + values[0] + "%");  
    }  
  
    @Override//提示任務(wù)的執(zhí)行結(jié)果  
    protected void onPostExecute(Boolean result) {  
        progressDialog.dismiss();  
        if (result) {  
            Toast.makeText(context, "下載成功", Toast.LENGTH_SHORT).show();  
        } else {  
            Toast.makeText(context, "下載失敗", Toast.LENGTH_SHORT).show();  
        }  
    }  
}  

任務(wù)的啟動(dòng)和停止只需要以下幾行代碼:

// 開始任務(wù)  
DownloadTask mDownloadTask  = new DownloadTask();  
mDownloadTask .execute();  
   
// 停止任務(wù)  
mDownloadTask .cancel(true);  

補(bǔ)充實(shí)例詳解Android中AsyncTask的使用

c.工作原理

  • 內(nèi)部有一個(gè)靜態(tài)的Handler對(duì)象即InternalHandler
    • 作用:將執(zhí)行環(huán)境從線程池切換到主線程;通過它來發(fā)送任務(wù)執(zhí)行的進(jìn)度以及執(zhí)行結(jié)束等消息豹绪。
    • 注意:必須在主線程中創(chuàng)建
  • 內(nèi)部有兩個(gè)線程池:
    • SerialExecutor:用于任務(wù)的排隊(duì)价淌,默認(rèn)是串行的線程池
    • THREAD_POOL_EXECUTOR:用于真正執(zhí)行任務(wù)。
  • 排隊(duì)執(zhí)行過程:
    • 把參數(shù)Params封裝為FutureTask對(duì)象瞒津,相當(dāng)于Runnable蝉衣;
    • 調(diào)用SerialExecutor.execute()將FutureTask插入到任務(wù)隊(duì)列tasks;
    • 若沒有正在活動(dòng)的AsyncTask任務(wù)巷蚪,則就會(huì)執(zhí)行下一個(gè)AsyncTask任務(wù)病毡。執(zhí)行完畢后會(huì)繼續(xù)執(zhí)行其他任務(wù)直到所有任務(wù)都完成。即默認(rèn)使用串行方式執(zhí)行任務(wù)屁柏。

注意:AsyncTask不適用于進(jìn)行特別耗時(shí)的后臺(tái)任務(wù)啦膜,而是建議用線程池有送。

推薦閱讀Android AsyncTask完全解析,帶你從源碼的角度徹底理解功戚、AsyncTask原理及不足


2.HandlerThread

a.HandlerThread是一個(gè)線程類娶眷,它繼承自Thread

與普通Thread的區(qū)別:具有消息循環(huán)的效果。原理:

  • 內(nèi)部HandlerThread.run()方法中有Looper啸臀,通過Looper.prepare()來創(chuàng)建消息隊(duì)列届宠,并通過Looper.loop()來開啟消息循環(huán)。

b實(shí)現(xiàn)方法

  • 實(shí)例化一個(gè)HandlerThread對(duì)象乘粒,參數(shù)是該線程的名稱豌注;
  • 通過 HandlerThread.start()開啟線程;
  • 實(shí)例化一個(gè)Handler并傳入HandlerThread中的looper對(duì)象灯萍,使得與HandlerThread綁定轧铁;
  • 利用Handler即可執(zhí)行異步任務(wù);
  • 當(dāng)不需要HandlerThread時(shí)旦棉,通過HandlerThread.quit()/quitSafely()方法來終止線程的執(zhí)行齿风。
private HandlerThread myHandlerThread ;  
private Handler handler ;  
@Override  
protected void onCreate(Bundle savedInstanceState) {  
    super.onCreate(savedInstanceState);  
   setContentView(R.layout.activity_main);  
   //實(shí)例化HandlerThread
   myHandlerThread = new HandlerThread("myHandler") ;  
   //開啟HandlerThread
   myHandlerThread.start();  
   //將Handler對(duì)象與HandlerThread線程綁定
   handler =new Handler(myHandlerThread.getLooper()){  
       @Override  
        publicvoid handleMessage(Message msg) {  
           super.handleMessage(msg);  
            // 這里接收Handler發(fā)來的消息,運(yùn)行在handler_thread線程中  
            //TODO...  
        }  
    };  
   
   //在主線程給Handler發(fā)送消息  
   handler.sendEmptyMessage(1) ;  
   new Thread(new Runnable() {  
       @Override  
        publicvoid run() {  
           //在子線程給Handler發(fā)送數(shù)據(jù)  
           handler.sendEmptyMessage(2) ;  
        }  
    }).start();  
}  
@Override  
protected void onDestroy() {  
   super.onDestroy();  
   //終止HandlerThread運(yùn)行
   myHandlerThread.quit() ;  
}  

補(bǔ)充實(shí)例Android 多線程之HandlerThread 完全詳解

c.用途:

  • 進(jìn)行串行異步通信
  • 構(gòu)造IntentService

在之前學(xué)習(xí)Handler機(jī)制時(shí)知道在子線程使用Handler的方法绑洛,其實(shí)HandlerThread的出現(xiàn)使得這一過程變得更加簡(jiǎn)便救斑,更多解析見淺析HandlerThread


3.IntentService

a.IntentService是一個(gè)繼承自Service的抽象類

b.優(yōu)點(diǎn):

  • 相比于線程:由于是服務(wù),優(yōu)先級(jí)比線程高真屯,更不容易被系統(tǒng)殺死脸候。因此較適合執(zhí)行一些高優(yōu)先級(jí)的后臺(tái)任務(wù)。
  • 相比于普通Service:可自動(dòng)創(chuàng)建子線程來執(zhí)行任務(wù)绑蔫,且任務(wù)執(zhí)行完畢后自動(dòng)退出运沦。

c.IntentService內(nèi)部封裝了HandlerThread和Handler,工作原理:

  • IntentService.onCreate()里創(chuàng)建一個(gè)Handle對(duì)象即HandlerThread配深,利用其內(nèi)部的Looper會(huì)實(shí)例化一個(gè)ServiceHandler對(duì)象携添;
  • 任務(wù)請(qǐng)求的Intent會(huì)被封裝到Message并通過ServiceHandler發(fā)送給Looper的MessageQueue,最終在HandlerThread中執(zhí)行篓叶;
  • ServiceHandler.handleMessage()中會(huì)調(diào)用IntentService.onHandleIntent()烈掠,可在該方法中處理后臺(tái)任務(wù)的邏輯。
流程圖

圖片來源Android IntentService的使用和源碼分析

d.使用方法:

  • 新建類并繼承IntentService澜共,重寫onHandleIntent()方法向叉,該方法:
    • 運(yùn)行在:子線程,因此可以去處理一些耗時(shí)操作嗦董。
    • 作用:從Intent參數(shù)中區(qū)分具體的任務(wù)并執(zhí)行這些任務(wù)
  • 在配置文件中進(jìn)行注冊(cè)母谎。
  • 在活動(dòng)中利用Intent實(shí)現(xiàn)IntentService的啟動(dòng):
Intent intent = new Intent(this, MyService.class);
intent.putExtra("xxx",xxx);  
startService(intent);//啟動(dòng)服務(wù)

具體實(shí)例見Service篇之IntentService

注意:無需手動(dòng)停止服務(wù),onHandleIntent()執(zhí)行結(jié)束之后京革,IntentService會(huì)自動(dòng)停止奇唤。

推薦閱讀Android多線程:IntentService用法&源碼分析


三.線程池

1.優(yōu)點(diǎn)

  • 重用線程池中的線程幸斥,避免線程的創(chuàng)建和銷毀帶來的性能消耗;
  • 有效控制線程池的最大并發(fā)數(shù)咬扇,避免大量的線程之間因互相搶占系統(tǒng)資源而導(dǎo)致阻塞現(xiàn)象甲葬;
  • 進(jìn)行線程管理,提供定時(shí)/循環(huán)間隔執(zhí)行等功能懈贺。
  • 線程池的概念來源:Java中的Executor经窖,它是一個(gè)接口。
  • 線程池的真正實(shí)現(xiàn):ThreadPoolExecutor梭灿,提供一系列參數(shù)來配置線程池画侣。
//構(gòu)造參數(shù)
public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue,
                              ThreadFactory threadFactory,
                              RejectedExecutionHandler handler) {
  • corePoolSize:核心線程數(shù)
    • 默認(rèn)情況下,核心線程會(huì)在線程中一直存活堡妒。
    • 當(dāng)設(shè)置ThreadPoolExecutor的allowCoreThreadTimeOut屬性為
      • true:表示核心線程閑置超過超時(shí)時(shí)長(zhǎng)配乱,會(huì)被回收;
      • false:表示核心線程不會(huì)被回收皮迟,會(huì)在線程池中一直存活搬泥。
  • maximumPoolSize:最大線程數(shù)
    • 當(dāng)活動(dòng)線程數(shù)達(dá)到這個(gè)數(shù)值后,后續(xù)的任務(wù)將會(huì)被阻塞伏尼。
  • keepAliveTime:非核心線程超時(shí)時(shí)間
    • 超過這個(gè)時(shí)長(zhǎng)忿檩,閑置的非核心線程就會(huì)被回收。
    • 當(dāng)設(shè)置ThreadPoolExecutor的allowCoreThreadTimeTout屬性為true時(shí)烦粒,keepAliveTime對(duì)核心線程同樣有效休溶。
  • unit:用于指定keepAliveTime參數(shù)的時(shí)間單位
    • 單位有:TimeUnit.MILLISECONDS代赁、TimeUnit.SECONDS扰她、TimeUnit.MINUTES等;
  • workQueue:任務(wù)隊(duì)列
    • 通過線程池的execute()方法提交的Runnable對(duì)象會(huì)存儲(chǔ)在這個(gè)參數(shù)中芭碍。
  • threadFactory:線程工廠徒役,可創(chuàng)建新線程
    • 是個(gè)接口,只有一個(gè)方法Thread newThread(Runnable r)窖壕。
  • handler:在線程池?zé)o法執(zhí)行新任務(wù)時(shí)進(jìn)行調(diào)度忧勿。

實(shí)例線程池的原理及實(shí)現(xiàn)

3.ThreadPoolExecutor的默認(rèn)工作策略

  • 若程池中的線程數(shù)量未達(dá)到核心線程數(shù),則會(huì)直接啟動(dòng)一個(gè)核心線程執(zhí)行任務(wù)瞻讽。
  • 若線程池中的線程數(shù)量已達(dá)到或者超過核心線程數(shù)量鸳吸,則任務(wù)會(huì)被插入到任務(wù)列表等待執(zhí)行。
    • 若任務(wù)無法插入到任務(wù)列表中速勇,往往由于任務(wù)列表已滿晌砾,此時(shí)如果
      • 線程數(shù)量未達(dá)到線程池最大線程數(shù),則會(huì)啟動(dòng)一個(gè)非核心線程執(zhí)行任務(wù)烦磁;
      • 線程數(shù)量已達(dá)到線程池規(guī)定的最大值养匈,則拒絕執(zhí)行此任務(wù)哼勇,ThreadPoolExecutor會(huì)調(diào)用RejectedExecutionHandler的rejectedExecution方法來通知調(diào)用者。

4.ThreadPoolExecutor線程池的分類:

  • FixThreadPool
    • 含義:線程數(shù)量固定的線程池呕乎,所有線程都是核心線程积担,當(dāng)線程空閑時(shí)不會(huì)被回收。
    • 特點(diǎn):能快速響應(yīng)外界請(qǐng)求猬仁。
  • CachedThreadPool
    • 含義:線程數(shù)量不定的線程池(最大線程數(shù)為Integer.MAX_VALUE)帝璧,只有非核心線程,空閑線程有超時(shí)機(jī)制湿刽,超時(shí)回收聋溜。
    • 特點(diǎn):適合于執(zhí)行大量的耗時(shí)較少的任務(wù)
  • ScheduledThreadPool
    • 含義:核心線程數(shù)量固定,非核心線程數(shù)量不定叭爱。
    • 特點(diǎn):定時(shí)任務(wù)和固定周期的任務(wù)撮躁。
  • SingleThreadExecutor
    • 含義:只有一個(gè)核心線程,可確保所有的任務(wù)都在同一個(gè)線程中按順序執(zhí)行买雾。
    • 特點(diǎn):無需處理線程同步問題把曼。

推薦閱讀Java四種線程池的使用


希望這篇文章對(duì)你有幫助~

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市漓穿,隨后出現(xiàn)的幾起案子嗤军,更是在濱河造成了極大的恐慌,老刑警劉巖晃危,帶你破解...
    沈念sama閱讀 206,126評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件叙赚,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡僚饭,警方通過查閱死者的電腦和手機(jī)震叮,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,254評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來鳍鸵,“玉大人苇瓣,你說我怎么就攤上這事〕ス裕” “怎么了击罪?”我有些...
    開封第一講書人閱讀 152,445評(píng)論 0 341
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)贪薪。 經(jīng)常有香客問我媳禁,道長(zhǎng),這世上最難降的妖魔是什么画切? 我笑而不...
    開封第一講書人閱讀 55,185評(píng)論 1 278
  • 正文 為了忘掉前任竣稽,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘丧枪。我一直安慰自己光涂,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,178評(píng)論 5 371
  • 文/花漫 我一把揭開白布拧烦。 她就那樣靜靜地躺著忘闻,像睡著了一般。 火紅的嫁衣襯著肌膚如雪恋博。 梳的紋絲不亂的頭發(fā)上齐佳,一...
    開封第一講書人閱讀 48,970評(píng)論 1 284
  • 那天,我揣著相機(jī)與錄音债沮,去河邊找鬼炼吴。 笑死,一個(gè)胖子當(dāng)著我的面吹牛疫衩,可吹牛的內(nèi)容都是我干的硅蹦。 我是一名探鬼主播,決...
    沈念sama閱讀 38,276評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼闷煤,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼童芹!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起鲤拿,我...
    開封第一講書人閱讀 36,927評(píng)論 0 259
  • 序言:老撾萬榮一對(duì)情侶失蹤假褪,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后近顷,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體生音,經(jīng)...
    沈念sama閱讀 43,400評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,883評(píng)論 2 323
  • 正文 我和宋清朗相戀三年窒升,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了缀遍。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 37,997評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡异剥,死狀恐怖瑟由,靈堂內(nèi)的尸體忽然破棺而出絮重,到底是詐尸還是另有隱情冤寿,我是刑警寧澤,帶...
    沈念sama閱讀 33,646評(píng)論 4 322
  • 正文 年R本政府宣布青伤,位于F島的核電站督怜,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏狠角。R本人自食惡果不足惜号杠,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,213評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧姨蟋,春花似錦屉凯、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,204評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至堂飞,卻和暖如春灌旧,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背绰筛。 一陣腳步聲響...
    開封第一講書人閱讀 31,423評(píng)論 1 260
  • 我被黑心中介騙來泰國(guó)打工枢泰, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人铝噩。 一個(gè)月前我還...
    沈念sama閱讀 45,423評(píng)論 2 352
  • 正文 我出身青樓衡蚂,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親骏庸。 傳聞我的和親對(duì)象是個(gè)殘疾皇子讳窟,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,722評(píng)論 2 345

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

  • Android中的線程 線程,在Android中是非常重要的敞恋,主線程處理UI界面丽啡,子線程處理耗時(shí)操作。如果在主線程...
    shenhuniurou閱讀 748評(píng)論 0 3
  • 從用途上來說硬猫,線程分為主線程和子線程补箍,主線程主要處理和界面相關(guān)的事情,子線程則往往用于執(zhí)行耗時(shí)操作啸蜜。 除了Thre...
    小柏不是大白閱讀 620評(píng)論 0 3
  • 主席(任玉剛)當(dāng)時(shí)在他群里發(fā)這書簡(jiǎn)介的時(shí)候坑雅,只看目錄就知道是我想要的,哈哈衬横,書還是有些難度的裹粤,不過真是一本超棒的書...
    HuDP閱讀 5,725評(píng)論 14 69
  • 詩歌的感覺 陽春三月,北方的雪花終于離去蜂林, 春風(fēng)一抹遥诉,吹醒了多少詩人的思緒, 松軟的泥土孕育了嫩綠的草芽噪叙, 詩歌的...
    子涵周雨閱讀 254評(píng)論 0 0
  • 在一個(gè)寒冷冬天的晚上矮锈,小明用自己兼職掙來的200元錢,去請(qǐng)他心儀的女生小花吃火鍋睁蕾“浚火鍋的蒸蒸熱氣债朵,溫暖著兩個(gè)漂泊在...
    斑點(diǎn)魚閱讀 621評(píng)論 0 0