Android讀書(shū)筆記(11)—— Android的線程和線程池

前言

在Android中责鳍,線程的形態(tài)有很多種:

  • AsyncTask封裝了線程池和Handler碾褂,主要為了方便開(kāi)發(fā)者在子線程中更新UI,底層是線程池历葛。
  • HandlerThread是具有消息循環(huán)的線程正塌,內(nèi)部可以使用handler嘀略,底層是Thread。
  • IntentService是一種Service乓诽,內(nèi)部采用HandlerThread來(lái)執(zhí)行任務(wù)帜羊,當(dāng)任務(wù)執(zhí)行完畢后IntentService會(huì)自動(dòng)退出。由于它是一種Service鸠天,所以不容易被系統(tǒng)殺死讼育,底層是Thread 。

操作系統(tǒng)中稠集,線程是操作系統(tǒng)調(diào)度的最小單元奶段,同時(shí)線程又是一種受限的系統(tǒng)資源(不可能無(wú)限產(chǎn)生),其創(chuàng)建和銷(xiāo)毀都會(huì)有相應(yīng)的開(kāi)銷(xiāo)剥纷。同時(shí)當(dāng)系統(tǒng)存在大量線程時(shí)痹籍,系統(tǒng)會(huì)通過(guò)時(shí)間片輪轉(zhuǎn)的方式調(diào)度每個(gè)線程,因此線程不可能做到絕對(duì)的并發(fā)晦鞋,除非線程數(shù)量小于等于CPU的核心數(shù)蹲缠。頻繁創(chuàng)建銷(xiāo)毀線程不明智,使用線程池是正確的做法鳖宾。線程池會(huì)緩存一定數(shù)量的線程吼砂,通過(guò)線程池就可以避免因?yàn)轭l繁創(chuàng)建和銷(xiāo)毀線程所帶來(lái)的系統(tǒng)開(kāi)銷(xiāo)。

一鼎文、主線程和子線程

主線程也叫UI線程渔肩,作用是運(yùn)行四大組件以及處理它們和用戶(hù)交互。子線程的作用是執(zhí)行耗時(shí)操作拇惋,比如I/O周偎,網(wǎng)絡(luò)請(qǐng)求等。從Android 3.0開(kāi)始撑帖,主線程中訪問(wèn)網(wǎng)絡(luò)將拋出異常蓉坎。

二、Android中的線程形態(tài)

1胡嘿、AsyncTask

AsyncTask是一種輕量級(jí)的異步任務(wù)類(lèi)蛉艾,封裝了Thread和Handler,可以在線程池中執(zhí)行后臺(tái)任務(wù)衷敌,然后把執(zhí)行的進(jìn)度最終的結(jié)果傳遞給主線程并更新UI勿侯。但并不適合進(jìn)行特別耗時(shí)的后臺(tái)任務(wù),對(duì)于特別耗時(shí)的任務(wù)來(lái)說(shuō), 建議使用線程池缴罗。

abstract class AsyncTask<Params, Progress, Result>

  • Params:入?yún)㈩?lèi)型
  • Progress:后臺(tái)任務(wù)的執(zhí)行進(jìn)度的類(lèi)型
  • Result:后臺(tái)任務(wù)的返回結(jié)果的類(lèi)型

如果不需要傳遞具體的參數(shù), 那么這三個(gè)泛型參數(shù)可以用Void來(lái)代替助琐。

1.1、四個(gè)核心方法
  • onPreExecute() void
    在主線程執(zhí)行, 在異步任務(wù)執(zhí)行之前, 此方法會(huì)被調(diào)用, 一般可以用于做一些準(zhǔn)備工作面氓。
  • doInBackground(Params... params) Result
    在線程池中執(zhí)行, 此方法用于執(zhí)行異步任務(wù), 參數(shù)params表示異步任務(wù)的輸入?yún)?shù)兵钮。 在此方法中可以通過(guò)publishProgress(Progress... values) void方法來(lái)更新任務(wù)的進(jìn)度, publishProgress()方法會(huì)調(diào)用onProgressUpdate()方法蛆橡。另外此方法需要返回計(jì)算結(jié)果給onPostExecute()
  • onProgressUpdate(Progress... values) void
    在主線程執(zhí)行,當(dāng)后臺(tái)任務(wù)publishProgress()時(shí)掘譬,會(huì)被調(diào)用泰演。
  • onPostExecute(Result res) void
    在主線程執(zhí)行, 在異步任務(wù)執(zhí)行之后, 此方法會(huì)被調(diào)用, 其中result參數(shù)是后臺(tái)任務(wù)的返回值, 即doInBackground的返回值。

除了上述的四種方法,還有onCancelled(), 它同樣在主線程執(zhí)行, 當(dāng)異步任務(wù)被取消時(shí)調(diào)用屁药,這個(gè)時(shí)候onPostExecute()則不會(huì)被調(diào)用.

1.2粥血、AsyncTask使用過(guò)程中的一些條件限制
  • AsyncTask的類(lèi)必須在主線程被加載, 這就意味著第一次訪問(wèn)AsyncTask必須發(fā)生在主線程。在Android 4.1及以上的版本已經(jīng)被系統(tǒng)自動(dòng)完成酿箭。
  • AsyncTask的對(duì)象必須在主線程中創(chuàng)建。
  • execute方法必須在UI線程調(diào)用趾娃。
  • 不要在程序中直接調(diào)用onPreExecute(), onPostExecute(), doInBackground和onProgressUpdate()
  • 一個(gè)AsyncTask對(duì)象只能執(zhí)行一次, 即只能調(diào)用一次execute()方法, 否則會(huì)報(bào)運(yùn)行時(shí)異常缭嫡。
  • AsyncTask采用了一個(gè)線程來(lái)串行的執(zhí)行任務(wù)。 盡管如此在3.0以后, 仍然可以通過(guò)AsyncTask#executeOnExecutor()方法來(lái)并行執(zhí)行任務(wù)抬闷。
1.3妇蛀、AsyncTask的工作原理

AsyncTask中有兩個(gè)線程池(SerialExecutor和THREAD_POOL_EXECUTOR)和一個(gè)Handler(InternalHandler), 其中線程池SerialExecutor用于任務(wù)的排列, 而線程池THREAD_POOL_EXECUTOR用于真正的執(zhí)行任務(wù), 而InternalHandler用于將執(zhí)行環(huán)境從線程切換到主線程, 其本質(zhì)仍然是線程的調(diào)用過(guò)程。

AsyncTask的排隊(duì)過(guò)程:首先系統(tǒng)會(huì)把AsyncTask#Params參數(shù)封裝成FutureTask對(duì)象, FutureTask是一個(gè)并發(fā)類(lèi), 在這里充當(dāng)了Runnable的作用. 接著這個(gè)FutureTask會(huì)交給SerialExecutor#execute()方法去處理. 這個(gè)方法首先會(huì)把FutureTask對(duì)象插入到任務(wù)隊(duì)列mTasks中, 如果這個(gè)時(shí)候沒(méi)有正在活動(dòng)AsyncTask任務(wù), 那么就會(huì)調(diào)用SerialExecutor#scheduleNext()方法來(lái)執(zhí)行下一個(gè)AsyncTask任務(wù). 同時(shí)當(dāng)一個(gè)AsyncTask任務(wù)執(zhí)行完后, AsyncTask會(huì)繼續(xù)執(zhí)行其他任務(wù)直到所有的任務(wù)都執(zhí)行完畢為止, 從這一點(diǎn)可以看出, 在默認(rèn)情況下, AsyncTask是串行執(zhí)行的笤成。

2评架、HandlerThread

HandlerThread繼承了Thread, 它是一種可以使用Handler的Thread, 它的實(shí)現(xiàn)也很簡(jiǎn)單, 就是run方法中通過(guò)Looper.prepare()來(lái)創(chuàng)建消息隊(duì)列, 并通過(guò)Looper.loop()來(lái)開(kāi)啟消息循環(huán), 這樣在實(shí)際的使用中就允許在HandlerThread中創(chuàng)建Handler.

從HandlerThread的實(shí)現(xiàn)來(lái)看, 它和普通的Thread有顯著的不同之處. 普通的Thread主要用于在run方法中執(zhí)行一個(gè)耗時(shí)任務(wù); 而HandlerThread在內(nèi)部創(chuàng)建了消息隊(duì)列, 外界需要通過(guò)Handler的消息方式來(lái)通知HandlerThread執(zhí)行一個(gè)具體的任務(wù). HandlerThread是一個(gè)很有用的類(lèi), 在Android中一個(gè)具體使用場(chǎng)景就是IntentService.

由于HandlerThread#run()是一個(gè)無(wú)線循環(huán)方法, 因此當(dāng)明確不需要再使用HandlerThread時(shí), 最好通過(guò)quit()或者quitSafely()方法來(lái)終止線程的執(zhí)行.

3、IntentService

IntentSercie是一種特殊的Service炕泳,繼承了Service并且是抽象類(lèi)纵诞,任務(wù)執(zhí)行完成后會(huì)自動(dòng)停止,優(yōu)先級(jí)遠(yuǎn)高于普通線程培遵,適合執(zhí)行一些高優(yōu)先級(jí)的后臺(tái)任務(wù)浙芙; IntentService封裝了HandlerThread和Handler

onCreate方法自動(dòng)創(chuàng)建一個(gè)HandlerThread,用它的Looper構(gòu)造了一個(gè)Handler對(duì)象mServiceHandler籽腕,這樣通過(guò)mServiceHandler發(fā)送的消息都會(huì)在HandlerThread執(zhí)行嗡呼;IntentServiced的onHandlerIntent方法是一個(gè)抽象方法,需要在子類(lèi)實(shí)現(xiàn)皇耗,onHandlerIntent方法執(zhí)行后南窗,stopSelt(int startId)就會(huì)停止服務(wù),如果存在多個(gè)后臺(tái)任務(wù)郎楼,執(zhí)行完最后一個(gè)stopSelf(int startId)才會(huì)停止服務(wù)万伤。

三、Android線程池

線程池優(yōu)點(diǎn):
1) 重用線程池的線程箭启,減少線程創(chuàng)建和銷(xiāo)毀帶來(lái)的性能開(kāi)銷(xiāo)
2) 控制線程池的最大并發(fā)數(shù)壕翩,避免大量線程互相搶系統(tǒng)資源導(dǎo)致阻塞
3) 提供定時(shí)執(zhí)行和間隔循環(huán)執(zhí)行功能

Android中的線程池的概念來(lái)源于Java中的Executor,Executor是一個(gè)接口, 真正的線程池的實(shí)現(xiàn)為ThreadPoolExecutor傅寡。Android的線程池大部分都是通過(guò)Executor提供的工廠方法創(chuàng)建的放妈。 ThreadPoolExecutor提供了一系列參數(shù)來(lái)配制線程池北救,通過(guò)不同的參數(shù)可以創(chuàng)建不同的線程池。 而從功能的特性來(lái)分的話可以分成四類(lèi)芜抒。

1珍策、ThreadPoolExecutor

ThreadPoolExecutor是線程池的真正實(shí)現(xiàn), 它的構(gòu)造方法提供了一系列參數(shù)來(lái)配置線程池, 這些參數(shù)將會(huì)直接影響到線程池的功能特性。

public ThreadPoolExecutor(int corePoolSize,
                 int maximumPoolSize,
                 long keepAliveTime,
                 TimeUnit unit,
                 BlockingQueue<Runnable> workQueue) {
    this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
    Executors.defaultThreadFactory(), defaultHandler);
}
  • corePoolSize: 線程池的核心線程數(shù), 默認(rèn)情況下, 核心線程會(huì)在線程池中一直存活, 即使都處于閑置狀態(tài). 如果將ThreadPoolExecutor#allowCoreThreadTimeOut屬性設(shè)置為true, 那么閑置的核心線程在等待新任務(wù)到來(lái)時(shí)會(huì)有超時(shí)的策略, 這個(gè)時(shí)間間隔由keepAliveTime屬性來(lái)決定 當(dāng)?shù)却龝r(shí)間超過(guò)了keepAliveTime設(shè)定的值那么核心線程將會(huì)終止
  • maximumPoolSize: 線程池所能容納的最大線程數(shù), 當(dāng)活動(dòng)線程數(shù)達(dá)到這個(gè)數(shù)值之后, 后續(xù)的任務(wù)將會(huì)被阻塞
  • keepAliveTime: 非核心線程閑置的超時(shí)時(shí)長(zhǎng), 超過(guò)這個(gè)時(shí)長(zhǎng), 非核心線程就會(huì)被回收
  • allowCoreThreadTimeOut這個(gè)屬性為true的時(shí)候, 這個(gè)屬性同樣會(huì)作用于核心線程
  • unit: 用于指定keepAliveTime參數(shù)的時(shí)間單位, 這是一個(gè)枚舉, 常用的有TimeUtil.MILLISECONDS(毫秒), TimeUtil.SECONDS(秒)以及TimeUtil.MINUTES(分)
  • workQueue: 線程池中的任務(wù)隊(duì)列, 通過(guò)線程池的execute方法提交的Runnable對(duì)象會(huì)存儲(chǔ)在這個(gè)參數(shù)中
  • threadFactory: 線程工廠, 為線程池提供創(chuàng)建新線程的功能. ThreadFactory是一個(gè)接口

ThreadPoolExecutor執(zhí)行任務(wù)大致遵循如下規(guī)則:

如果線程池中的線程數(shù)量未達(dá)到核心線程的數(shù)量, 那么會(huì)直接啟動(dòng)一個(gè)核心線程來(lái)執(zhí)行任務(wù).
如果線程池中的線程數(shù)量已經(jīng)達(dá)到或者超過(guò)核心線程的數(shù)量, 那么任務(wù)會(huì)被插入到任務(wù)隊(duì)列中排隊(duì)等待執(zhí)行.
如果在步驟2中無(wú)法將任務(wù)插入到任務(wù)隊(duì)列中, 這通常是因?yàn)槿蝿?wù)隊(duì)列已滿(mǎn), 這個(gè)時(shí)候如果線程數(shù)量未達(dá)到線程池的規(guī)定的最大值, 那么會(huì)立刻啟動(dòng)一個(gè)非核心線程來(lái)執(zhí)行任務(wù).
如果步驟3中的線程數(shù)量已經(jīng)達(dá)到最大值的時(shí)候, 那么會(huì)拒絕執(zhí)行此任務(wù),ThreadPoolExecutor會(huì)調(diào)用RejectedExecution方法來(lái)通知調(diào)用者宅倒。

AsyncTask的THREAD_POOL_EXECUTOR線程池配置:

  • 核心線程數(shù)等于CPU核心數(shù)+1
  • 線程池最大線程數(shù)為CPU核心數(shù)的2倍+1
  • 核心線程無(wú)超時(shí)機(jī)制攘宙,非核心線程的閑置超時(shí)時(shí)間為1秒
  • 任務(wù)隊(duì)列容量是128

2、線程池的分類(lèi)

  • FixedThreadPool
    通過(guò)Executor#newFixedThreadPool()方法來(lái)創(chuàng)建. 它是一種線程數(shù)量固定的線程池, 當(dāng)線程處于空閑狀態(tài)時(shí), 它們并不會(huì)被回收, 除非線程池關(guān)閉了. 當(dāng)所有的線程都處于活動(dòng)狀態(tài)時(shí), 新任務(wù)都會(huì)處于等待狀態(tài), 直到有線程空閑出來(lái). 由于FixedThreadPool只有核心線程并且這些核心線程不會(huì)被回收, 這意味著它能夠更加快速地響應(yīng)外界的請(qǐng)求.

  • CachedThreadPool
    通過(guò)Executor#newCachedThreadPool()方法來(lái)創(chuàng)建. 它是一種線程數(shù)量不定的線程池, 它只有非核心線程, 并且其最大值線程數(shù)為Integer.MAX_VALUE. 這就可以認(rèn)為這個(gè)最大線程數(shù)為任意大了. 當(dāng)線程池中的線程都處于活動(dòng)的時(shí)候, 線程池會(huì)創(chuàng)建新的線程來(lái)處理新任務(wù), 否則就會(huì)利用空閑的線程來(lái)處理新任務(wù). 線程池中的空閑線程都有超時(shí)機(jī)制, 這個(gè)超時(shí)時(shí)長(zhǎng)為60S, 超過(guò)這個(gè)時(shí)間那么空閑線程就會(huì)被回收.
    和FixedThreadPool不同的是, CachedThreadPool的任務(wù)隊(duì)列其實(shí)相當(dāng)于一個(gè)空集合, 這將導(dǎo)致任何任務(wù)都會(huì)立即被執(zhí)行, 因?yàn)樵谶@種場(chǎng)景下SynchronousQueue是無(wú)法插入任務(wù)的. SynchronousQueue是一個(gè)非常特殊的隊(duì)列, 在很多情況下可以把它簡(jiǎn)單理解為一個(gè)無(wú)法存儲(chǔ)元素的隊(duì)列. 在實(shí)際使用中很少使用.這類(lèi)線程比較適合執(zhí)行大量的耗時(shí)較少的任務(wù)

  • ScheduledThreadPool
    通過(guò)Executor#newScheduledThreadPool()方法來(lái)創(chuàng)建. 它的核心線程數(shù)量是固定的, 而非核心線程數(shù)是沒(méi)有限制的, 并且當(dāng)非核心線程閑置時(shí)會(huì)立刻被回收掉. 這類(lèi)線程池用于執(zhí)行定時(shí)任務(wù)和具有固定周期的重復(fù)任務(wù)

  • SingleThreadExecutor
    通過(guò)Executor#newSingleThreadPool()方法來(lái)創(chuàng)建. 這類(lèi)線程池內(nèi)部只有一個(gè)核心線程, 它確保所有的任務(wù)都在同一個(gè)線程中按順序執(zhí)行. 這類(lèi)線程池意義在于統(tǒng)一所有的外界任務(wù)到一個(gè)線程中, 這使得在這些任務(wù)之間不需要處理線程同步的問(wèn)題

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末拐迁,一起剝皮案震驚了整個(gè)濱河市蹭劈,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌线召,老刑警劉巖铺韧,帶你破解...
    沈念sama閱讀 218,284評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異缓淹,居然都是意外死亡哈打,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,115評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén)讯壶,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)料仗,“玉大人,你說(shuō)我怎么就攤上這事伏蚊×⒃” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 164,614評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵丙挽,是天一觀的道長(zhǎng)肺孵。 經(jīng)常有香客問(wèn)我,道長(zhǎng)颜阐,這世上最難降的妖魔是什么平窘? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,671評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮凳怨,結(jié)果婚禮上瑰艘,老公的妹妹穿的比我還像新娘。我一直安慰自己肤舞,他們只是感情好紫新,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,699評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著李剖,像睡著了一般芒率。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上篙顺,一...
    開(kāi)封第一講書(shū)人閱讀 51,562評(píng)論 1 305
  • 那天偶芍,我揣著相機(jī)與錄音充择,去河邊找鬼。 笑死匪蟀,一個(gè)胖子當(dāng)著我的面吹牛椎麦,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播材彪,決...
    沈念sama閱讀 40,309評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼观挎,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了段化?” 一聲冷哼從身側(cè)響起嘁捷,我...
    開(kāi)封第一講書(shū)人閱讀 39,223評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎穗泵,沒(méi)想到半個(gè)月后普气,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,668評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡佃延,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,859評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了夷磕。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片履肃。...
    茶點(diǎn)故事閱讀 39,981評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖坐桩,靈堂內(nèi)的尸體忽然破棺而出尺棋,到底是詐尸還是另有隱情,我是刑警寧澤绵跷,帶...
    沈念sama閱讀 35,705評(píng)論 5 347
  • 正文 年R本政府宣布膘螟,位于F島的核電站,受9級(jí)特大地震影響碾局,放射性物質(zhì)發(fā)生泄漏荆残。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,310評(píng)論 3 330
  • 文/蒙蒙 一净当、第九天 我趴在偏房一處隱蔽的房頂上張望内斯。 院中可真熱鬧,春花似錦像啼、人聲如沸俘闯。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,904評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)真朗。三九已至,卻和暖如春僧诚,著一層夾襖步出監(jiān)牢的瞬間遮婶,已是汗流浹背蝗碎。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,023評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留蹭睡,地道東北人衍菱。 一個(gè)月前我還...
    沈念sama閱讀 48,146評(píng)論 3 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像肩豁,于是被迫代替她去往敵國(guó)和親脊串。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,933評(píng)論 2 355

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

  • Android中的線程 線程清钥,在Android中是非常重要的琼锋,主線程處理UI界面,子線程處理耗時(shí)操作祟昭。如果在主線程...
    shenhuniurou閱讀 755評(píng)論 0 3
  • 從用途上來(lái)說(shuō)缕坎,線程分為主線程和子線程,主線程主要處理和界面相關(guān)的事情篡悟,子線程則往往用于執(zhí)行耗時(shí)操作谜叹。 除了Thre...
    小柏不是大白閱讀 629評(píng)論 0 3
  • 主席(任玉剛)當(dāng)時(shí)在他群里發(fā)這書(shū)簡(jiǎn)介的時(shí)候,只看目錄就知道是我想要的搬葬,哈哈荷腊,書(shū)還是有些難度的,不過(guò)真是一本超棒的書(shū)...
    HuDP閱讀 5,740評(píng)論 14 69
  • 這是致前任的一篇日記 提起前任,大家應(yīng)該都不會(huì)陌生抡锈,前任對(duì)你來(lái)說(shuō)是什么呢疾忍?是一段記憶,還是一段不可觸碰的傷痛床三。對(duì)你...
    愛(ài)笑de小美閱讀 259評(píng)論 0 1
  • 不知道是我的問(wèn)題還是誰(shuí)的問(wèn)題一罩,我覺(jué)得我身邊的他們都是病孩子,也包括我勿璃。 有時(shí)候也不知道我在思考什么擒抛,渾渾噩噩一整天...
    李六六六閱讀 365評(píng)論 0 0