Android Picasso源碼解析(一)

參考文章:

Picasso源碼解析

一豺撑、簡(jiǎn)介

介紹:Picasso,可譯為“畢加索”,是Android中一個(gè)圖片加載開(kāi)源庫(kù)紊婉。

源碼地址:https://github.com/square/picasso

二、功能特點(diǎn)

1辑舷、功能列表



2喻犁、功能介紹

2.1 圖片的異部加載


2.2 圖片轉(zhuǎn)換

使用最少的內(nèi)存完成復(fù)雜的圖片轉(zhuǎn)換,轉(zhuǎn)換圖片以適合所顯示的ImageView何缓,來(lái)減少內(nèi)存消耗

也可以customTransformer方法肢础,進(jìn)行圖片的具體調(diào)整。



2.3?加載過(guò)程 & 錯(cuò)誤處理

Picasso支持加載過(guò)程中和加載錯(cuò)誤時(shí)顯示對(duì)應(yīng)圖片碌廓。


2.4 在Adapter中的回收不在視野的ImageView和取消已經(jīng)回收的ImageView下載進(jìn)程

2.5 從不同資源源加載

支持多種數(shù)據(jù)源 網(wǎng)絡(luò)传轰、本地、資源谷婆、Assets 等

//加載資源文件

Picasso.with(context).load(R.drawable.landing_screen).into(imageView1);

//加載本地文件

Picasso.with(context).load(new File("/images/oprah_bees.gif")).into(imageView2);

2.6 自動(dòng)添加磁盤和內(nèi)存二級(jí)緩存功能

2.7 支持優(yōu)先級(jí)處理

每次任務(wù)調(diào)度前會(huì)選擇優(yōu)先級(jí)高的任務(wù)慨蛙,比如 App 頁(yè)面中 Banner 的優(yōu)先級(jí)高于 Icon 時(shí)就很適用。

2.8 支持飛行模式纪挎、并發(fā)線程數(shù)根據(jù)網(wǎng)絡(luò)類型而變

手機(jī)切換到飛行模式或網(wǎng)絡(luò)類型變換時(shí)會(huì)自動(dòng)調(diào)整線程池最大并發(fā)數(shù)期贫,比如 wifi 最大并發(fā)為 4, 4g 為 3异袄,3g 為 2

2.9 “無(wú)”本地緩存

無(wú)”本地緩存唯灵,不是說(shuō)沒(méi)有本地緩存,而是 Picasso 自己沒(méi)有實(shí)現(xiàn)隙轻,交給了 Square 的另外一個(gè)網(wǎng)絡(luò)庫(kù) okhttp 去實(shí)現(xiàn)埠帕,這樣的好處是可以通過(guò)請(qǐng)求 Response Header 中的 Cache-Control 及 Expired 控制圖片的過(guò)期時(shí)間垢揩。


三、Picasso源碼解析

Picasso.with(this).load(imageUrl).into(imageView)

3.1? with


一個(gè)單例模式敛瓷,為了保證線程安全叁巨,使用的是雙重校驗(yàn)鎖。在Picasso創(chuàng)建的過(guò)程中又使用了Builder模式呐籽,最大的特點(diǎn)就是鏈?zhǔn)秸{(diào)用锋勺,使調(diào)用者的代碼邏輯簡(jiǎn)潔,同時(shí)擴(kuò)展性非常好狡蝶。下面我看一下new Builder()中的方法庶橱。

在Builder的構(gòu)造方法中就只是獲取到當(dāng)前應(yīng)用級(jí)別的上下文,也就說(shuō)明了Picasso是針對(duì)應(yīng)用級(jí)別的使用贪惹,不會(huì)是隨著Activity或是Fragment的生命周期而產(chǎn)生變化苏章,只有當(dāng)當(dāng)前的應(yīng)用退出或是銷毀時(shí)Picasso才會(huì)停止它的行為。

接下來(lái)奏瞬,我們看看build方法中到底做了什么事情枫绅。

在這個(gè)方法中主要初始化了Downloader、LruCache硼端、PicassoExecutorService并淋、RequestTransformer、Stats珍昨、Dispatcher县耽、并且返回一個(gè)Picasso對(duì)象。

3.1.1? downloader 下載器

首先镣典,我們先看downloader下載器酬诀,如果downloader==null的話,就會(huì)執(zhí)行Utils.createDefaultDownloader(context)方法去創(chuàng)建一個(gè)下載器骆撇。

createDefaultDownloader方法中首先使用java反射機(jī)制來(lái)查找項(xiàng)目中是否使用了okhttp網(wǎng)絡(luò)加載框架瞒御,如果使用了則會(huì)使用okhttp作為圖片的加載方式,如果沒(méi)有使用神郊,則會(huì)使用內(nèi)置的封裝加載器UrlConnectionDownloader肴裙。

注:由于okhttp3的包名已更換,所以在這里都是使用內(nèi)置的封裝下載器涌乳,這個(gè)是一個(gè)小bug等待完善蜻懦。當(dāng)修復(fù)之后Picasso+okhttp3則是最理想的加載方式。

當(dāng)然我們自己也可以自定義下載器夕晓,使用okhttp3 作為加載器宛乃。代碼如下:

OkHttp3Downloader的下載地址:

https://github.com/JakeWharton/picasso2-okhttp3-downloader


接下來(lái)我們先分析OkHttpDownloader,然后在分析UrlConnectionDownloader,看看他們?cè)创a中到底實(shí)現(xiàn)了什么東西征炼。

OkHttpDownloader

OkHttpDownloader的構(gòu)造方法

在構(gòu)造方法中通過(guò)Utils.createDefaultCacheDir(context)設(shè)置了文件緩存


private static final intMIN_DISK_CACHE_SIZE=5*1024*1024;// 5MB

private static final intMAX_DISK_CACHE_SIZE=50*1024*1024;// 50MB

通過(guò)Utils.calculateDiskCacheSize(cacheDir)析既,設(shè)置緩存的大小。

其中StatFs用于獲取存儲(chǔ)空間谆奥。

getBlockCount():文件系統(tǒng)中總的存儲(chǔ)區(qū)塊的數(shù)量眼坏;

getBlockSize():文件系統(tǒng)中每個(gè)存儲(chǔ)區(qū)塊的字節(jié)數(shù);

最大緩存大小是50M酸些。

通過(guò)defaultOkHttpClient()方法設(shè)置的OkHttpClient請(qǐng)求客戶端宰译。


UrlConnectionDownloader? 接下來(lái)分析UrlConnectionDownloader? 這個(gè)默認(rèn)的下載器。

UrlConnectionDownloader中使用的是系統(tǒng)自帶的HttpURLConnection進(jìn)行網(wǎng)絡(luò)請(qǐng)求的魄懂。

這個(gè)設(shè)置的緩存大小是和OkHttpDownloader大小是一致的沿侈。

static final intDEFAULT_WRITE_TIMEOUT_MILLIS=20*1000;// 20s

static final intDEFAULT_CONNECT_TIMEOUT_MILLIS=15*1000;// 15s


3.1.2 LruCache

Retrofit的默認(rèn)文件緩存采用的是LruCache。

LruCache的構(gòu)造方法如下:


通過(guò)Utils.calculateMemoryCacheSize(context)市栗,設(shè)置了緩存大小缀拭。

activityManager.getLargeMemoryClass(),為單個(gè)應(yīng)用的最大內(nèi)存使用。


LruCache的內(nèi)部實(shí)現(xiàn)是采用的LinkedHashMap肃廓,來(lái)保存緩存圖片智厌。

LinkedHashMap:它繼承與HashMap诲泌、底層使用哈希表與雙向鏈表來(lái)保存所有元素盲赊,

LinkedHashMap是Hash表和鏈表的實(shí)現(xiàn),并且依靠著雙向鏈表保證了迭代順序是插入的順序敷扫。雙向循環(huán)鏈表哀蘑。

HashMap:它根據(jù)鍵的HashCode值存儲(chǔ)數(shù)據(jù),根據(jù)鍵可以直接獲取它的值,具有很快的訪問(wèn)速度葵第,遍歷時(shí)绘迁,取得數(shù)據(jù)的順序是完全隨機(jī)的。

區(qū)別在于HashMap并不是按插入次序順序存放的卒密,而LinkedHashMap是順序存放的缀台。

關(guān)于HashMap和LinkedHashMap的源碼分析,我們?nèi)蘸笤斀狻?/b>

我們首先分析LruCache的set方法哮奇。

在set方法中膛腐,最終調(diào)用了map.put()方法,將數(shù)據(jù)放到Hash表里面鼎俘。在這個(gè)方法的最后有一個(gè)trimToSize(maxSize)哲身,他到底實(shí)現(xiàn)了什么尼?贸伐,首先我們看看它的源碼實(shí)現(xiàn)勘天。

從源碼中,我們看出,當(dāng)所插入的元素大小size大于maxSize時(shí)脯丝,LinkHashMap就把最舊的一個(gè)元素刪除掉商膊。get方法相對(duì)簡(jiǎn)單,我們就看一下源碼實(shí)現(xiàn)。

LruCache.get()方法:

3.1.3? PicassoExecutorService線程池

PicassoExecutorService的構(gòu)造方法如下圖所示:

PicassoExecutorService繼承的是ThreadPoolExecutor線程池

談到線程池讨永,我們先了解一下線程池的有點(diǎn):

重用線程池中的線程盖溺, 避免因?yàn)榫€程的創(chuàng)建和銷毀所帶來(lái)的性能開(kāi)銷.

有效控制線程池中的最大并發(fā)數(shù),避免大量線程之間因?yàn)橄嗷屨枷到y(tǒng)資源而導(dǎo)致的阻塞現(xiàn)象.

能夠?qū)€程進(jìn)行簡(jiǎn)單的管理潦匈,可提供定時(shí)執(zhí)行和按照指定時(shí)間間隔循環(huán)執(zhí)行等功能.

ThreadPoolExecutor 的配置參數(shù)

corePoolSize: 線程池的核心線程數(shù),默認(rèn)情況下赚导, 核心線程會(huì)在線程池中一直存活茬缩, 即使處于閑置狀態(tài). 但如果將allowCoreThreadTimeOut設(shè)置為true的話, 那么核心線程也會(huì)有超時(shí)機(jī)制, 在keepAliveTime設(shè)置的時(shí)間過(guò)后吼旧, 核心線程也會(huì)被終止.

maximumPoolSize: 最大的線程數(shù)凰锡, 包括核心線程, 也包括非核心線程圈暗, 在線程數(shù)達(dá)到這個(gè)值后掂为,新來(lái)的任務(wù)將會(huì)被阻塞.

keepAliveTime: 超時(shí)的時(shí)間, 閑置的非核心線程超過(guò)這個(gè)時(shí)長(zhǎng)员串,講會(huì)被銷毀回收勇哗, 當(dāng)allowCoreThreadTimeOut為true時(shí),這個(gè)值也作用于核心線程.

unit:超時(shí)時(shí)間的時(shí)間單位.

workQueue:線程池的任務(wù)隊(duì)列寸齐, 通過(guò)execute方法提交的runnable對(duì)象會(huì)存儲(chǔ)在這個(gè)隊(duì)列中.

threadFactory: 線程工廠, 為線程池提供創(chuàng)建新線程的功能.

handler: 任務(wù)無(wú)法執(zhí)行時(shí)欲诺,回調(diào)handler的rejectedExecution方法來(lái)通知調(diào)用者.

在這個(gè)構(gòu)造方法中,我們重點(diǎn)了解PriorityBlockingQueue和Utils.PicassoThreadFactory()兩個(gè)類或者功能方法渺鹦。

PriorityBlockingQueue:它是無(wú)界阻塞隊(duì)列扰法,容量是無(wú)限的,它使用與類PriorityQueue相同的順序規(guī)則毅厚。它是線程安全的塞颁,是阻塞的,具體詳解會(huì)在簡(jiǎn)書(shū)數(shù)據(jù)結(jié)構(gòu)中了解吸耿。

PicassoThreadFactory()最終使用的是PicassoThread線程工廠祠锣。我們簡(jiǎn)單了解PicassoThread的實(shí)現(xiàn)。

3.1.4 RequestTransformer

RequestTransformer主要是對(duì)RequestCreator創(chuàng)建的Request進(jìn)行轉(zhuǎn)換珍语,默認(rèn)對(duì)Request對(duì)象不做處理锤岸。源碼中也證實(shí)了這一點(diǎn)。

3.1.5 Stats 圖片的狀態(tài)

Stats的構(gòu)造方法如下:stats主要是用來(lái)統(tǒng)計(jì)緩存板乙,下載數(shù)量等數(shù)據(jù)是偷,一言以蔽之拳氢,就是保存圖片的一些狀態(tài)信息。

HandlerThread的詳解請(qǐng)閱讀handlerThread詳解

HandlerThread的主要優(yōu)點(diǎn)在于他是用的是子線程的Looper,所以說(shuō)不占用主線程度 資源蛋铆。

Stats里面自己實(shí)現(xiàn)了一個(gè)Handler馋评,代碼如下:


3.1.6? Dispatcher? 核心類

這個(gè)類在這里起到了一個(gè)調(diào)度器的作用,圖片要不要開(kāi)始下載以及下載后Bitmap的返回都是通過(guò)這個(gè)調(diào)度器來(lái)執(zhí)行的刺啦,后面進(jìn)行進(jìn)行詳細(xì)分析留特。我們先看一下Dispathcher的核心構(gòu)造方法。

控制的中心玛瘸,控制線程的加載和取消蜕青、網(wǎng)絡(luò)監(jiān)聽(tīng)、消息處理等糊渊。

幾個(gè)重要的參數(shù)右核,我們上面已經(jīng)介紹了。主要簡(jiǎn)單介紹DispatcherThread和DispatcherHandler渺绒。

DispatcherThread是一個(gè)HandlerThread,DispatcherHandler是自定義的消息分發(fā)的贺喝。源碼如下:

我們以dispatchSubmit為例。最終會(huì)調(diào)用Dispatcher的dispatchSubmit()方法宗兼。

Dispatcher的dispatchSubmit()方法主要是獲取BitmapHunter實(shí)例躏鱼,由這個(gè)實(shí)例來(lái)執(zhí)行實(shí)際的下載操作。BitmapHunter本身是Runnable的一個(gè)實(shí)現(xiàn)殷绍,而這個(gè)實(shí)例最終是交由Picasso線程池進(jìn)行運(yùn)行的染苛。這個(gè)實(shí)例最終是要放到this.hunterMap=newLinkedHashMap(),循環(huán)雙向隊(duì)列中篡帕。

那么這個(gè)BitmapHunter加載圖片成功或失敗后是怎么通知UI的呢殖侵?我們前面提到Dispatcher在Picasso中起到了一個(gè)調(diào)度器的作用贸呢,當(dāng)圖片加載完畢后自然也是通過(guò)這個(gè)調(diào)度器來(lái)更新UI镰烧,上面我們得到BitmapHunter的run方法會(huì)執(zhí)行響應(yīng)的下載任務(wù),那么我們就去這個(gè)run方法中去看看楞陷。

BitmapHunter.java

我們可以看到成功就會(huì)調(diào)用dispatcher.dispatchComplete(this)方法怔鳖,失敗就會(huì)調(diào)用dispatcher.dispatchFailed(this)方法。接下來(lái)我們就去Dispather方法中看看就這個(gè)是如何實(shí)現(xiàn)的固蛾。源碼如下:

經(jīng)過(guò)handler消息處理后结执,就會(huì)執(zhí)行dispatcher.performComplete(hunter)或者dispatcher.performError(hunter, false)。

圖片下載完成之后艾凯,首先放到LruCache中献幔,其實(shí)就是把操作先暫存在一個(gè)list中,等空閑的時(shí)候再拿出來(lái)處理趾诗,這樣做得好處也是盡量減少主線程的執(zhí)行時(shí)間蜡感,一方面防止ANR蹬蚁,另一方面快速返回,響應(yīng)頁(yè)面的其他渲染操作郑兴,防止卡頓用戶界面犀斋。然后下載任務(wù)從hunterMap刪除。然后執(zhí)行batch(hunter)方法情连。

private static final intBATCH_DELAY=200;// ms

handler.sendEmptyMessageDelayed(HUNTER_DELAY_NEXT_BATCH,BATCH_DELAY);

延時(shí)200毫秒之后叽粹,就來(lái)到了handlerMessage方法中。最終執(zhí)行dispatcher.performBatchComplete()方法却舀。

這個(gè)mainThreadHandler是在Dispatcher實(shí)例化時(shí)由外部傳遞進(jìn)來(lái)的虫几,我們?cè)谇懊娴姆治鲋锌吹剑琍icasso在通過(guò)Builder創(chuàng)建時(shí)會(huì)對(duì)Dispatcher進(jìn)行實(shí)例化挽拔,在那個(gè)地方將主線程的handler傳了進(jìn)來(lái)持钉,我們回到Picasso這個(gè)類,看到其有一個(gè)靜態(tài)成員變量HANDLER篱昔,這樣我們也就清楚了每强。

執(zhí)行到這里,圖片已經(jīng)馬上出來(lái)了州刽,hunter.picasso.complete(hunter)空执,Picasso中一個(gè)Action提供了請(qǐng)求前后的銜接工作,對(duì)于我們現(xiàn)在的情況穗椅,Picasso使用了ImageViewAction來(lái)進(jìn)行處理辨绊,也就是在ImageViewAction中的complete方法完成了最后的圖片渲染工作。

最后調(diào)用了PicassoDrawable.setBitmap(target,context,result,from,noFade,indicatorsEnabled)方法匹表。

最后執(zhí)行PicassoDrawable门坷,從這個(gè)構(gòu)造方法中,我們就明白了placeholder是如何設(shè)置的啦袍镀。

在PicassoDrawable方法中默蚌,實(shí)現(xiàn)了這個(gè)功能。

dispatcher.performError(hunter, false)就不帶大家詳細(xì)分析了苇羡。最后后調(diào)用ImageViewAction的error方法绸吸。

至此Dispather分析完畢,至此我們留下一個(gè)疑問(wèn)Dispather.dispatchSubmit(Action action),從哪里開(kāi)始調(diào)用的设江。

3.2 load()方法

接下來(lái)我們分析锦茁,Picasso中的load方法,圖片是如何進(jìn)行網(wǎng)絡(luò)請(qǐng)求的叉存。

待續(xù)码俩。。歼捏。稿存。够傍。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市挠铲,隨后出現(xiàn)的幾起案子冕屯,更是在濱河造成了極大的恐慌,老刑警劉巖拂苹,帶你破解...
    沈念sama閱讀 216,402評(píng)論 6 499
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件安聘,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡瓢棒,警方通過(guò)查閱死者的電腦和手機(jī)浴韭,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,377評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)脯宿,“玉大人念颈,你說(shuō)我怎么就攤上這事×梗” “怎么了榴芳?”我有些...
    開(kāi)封第一講書(shū)人閱讀 162,483評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)跺撼。 經(jīng)常有香客問(wèn)我窟感,道長(zhǎng),這世上最難降的妖魔是什么歉井? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,165評(píng)論 1 292
  • 正文 為了忘掉前任柿祈,我火速辦了婚禮,結(jié)果婚禮上哩至,老公的妹妹穿的比我還像新娘躏嚎。我一直安慰自己,他們只是感情好菩貌,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,176評(píng)論 6 388
  • 文/花漫 我一把揭開(kāi)白布卢佣。 她就那樣靜靜地躺著,像睡著了一般菜谣。 火紅的嫁衣襯著肌膚如雪珠漂。 梳的紋絲不亂的頭發(fā)上晚缩,一...
    開(kāi)封第一講書(shū)人閱讀 51,146評(píng)論 1 297
  • 那天尾膊,我揣著相機(jī)與錄音,去河邊找鬼荞彼。 笑死冈敛,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的鸣皂。 我是一名探鬼主播抓谴,決...
    沈念sama閱讀 40,032評(píng)論 3 417
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼暮蹂,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了癌压?” 一聲冷哼從身側(cè)響起仰泻,我...
    開(kāi)封第一講書(shū)人閱讀 38,896評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎滩届,沒(méi)想到半個(gè)月后集侯,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,311評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡帜消,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,536評(píng)論 2 332
  • 正文 我和宋清朗相戀三年棠枉,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片泡挺。...
    茶點(diǎn)故事閱讀 39,696評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡辈讶,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出娄猫,到底是詐尸還是另有隱情贱除,我是刑警寧澤,帶...
    沈念sama閱讀 35,413評(píng)論 5 343
  • 正文 年R本政府宣布媳溺,位于F島的核電站勘伺,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏褂删。R本人自食惡果不足惜飞醉,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,008評(píng)論 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望屯阀。 院中可真熱鬧缅帘,春花似錦、人聲如沸难衰。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,659評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)盖袭。三九已至失暂,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間鳄虱,已是汗流浹背弟塞。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,815評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留拙已,地道東北人决记。 一個(gè)月前我還...
    沈念sama閱讀 47,698評(píng)論 2 368
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像倍踪,于是被迫代替她去往敵國(guó)和親系宫。 傳聞我的和親對(duì)象是個(gè)殘疾皇子索昂,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,592評(píng)論 2 353

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

  • Picasso,看的版本是v.2.5.2 使用方法扩借,大概這么幾種加載資源的形式 還可以對(duì)圖片進(jìn)行一些操作:設(shè)置大小...
    Jinjins1129閱讀 348評(píng)論 0 3
  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,071評(píng)論 25 707
  • 一. 概述 Picasso是Square出品的一個(gè)非常精簡(jiǎn)的圖片加載及緩存庫(kù)椒惨,其主要特點(diǎn)包括: 易寫(xiě)易讀的流式編程...
    SparkInLee閱讀 1,090評(píng)論 2 11
  • 昨夜無(wú)事望月宮, 宮里嫦娥空自嘆潮罪! 遙問(wèn)空嘆為哪般框产? 緣來(lái)天下第一人。 曉覺(jué)起身隔窗問(wèn)错洁, 均是一人誰(shuí)二人秉宿? 鞘中殘...
    云先生_2017閱讀 186評(píng)論 1 2
  • 目前為止我最寶貴財(cái)富就是我的家庭,我覺(jué)得很幸福屯碴。我家人對(duì)我很好描睦,也教我對(duì)別人也好。 我希望我將來(lái)能擁有的就是自由的...
    可愛(ài)的三姑閱讀 114評(píng)論 2 0