Android進(jìn)程保活

一鼎天、前言

Android系統(tǒng)進(jìn)程币蹋活主要包括兩個(gè)層面:
1、提高進(jìn)程的優(yōu)先級(jí)斋射,從而降低進(jìn)程被殺死的概率育勺。
2但荤、在進(jìn)程被殺死后,對(duì)進(jìn)程進(jìn)行拉活涧至。

我們先來(lái)看一下進(jìn)程的優(yōu)先級(jí):
Android系統(tǒng)將盡量保持應(yīng)用進(jìn)程腹躁,但是為了新建進(jìn)程或者運(yùn)行更重要的進(jìn)程,最終需要清除舊進(jìn)程來(lái)回收內(nèi)存南蓬。
為了確定保留或者終止哪些進(jìn)程纺非,系統(tǒng)會(huì)根據(jù)進(jìn)程中正在運(yùn)行的組件以及這些組件的狀態(tài),將每個(gè)進(jìn)程放入“重要性層次結(jié)構(gòu)”中赘方。在對(duì)進(jìn)程進(jìn)行終止時(shí)烧颖,首先會(huì)清除一些重要性低一點(diǎn)的進(jìn)程,以此類(lèi)推窄陡,以回收系統(tǒng)資源炕淮。

根據(jù)進(jìn)程的優(yōu)先級(jí),可以將進(jìn)行劃分為5級(jí):
1跳夭、前臺(tái)進(jìn)程(Foreground process)
2涂圆、可見(jiàn)進(jìn)程(Visible process)
3、服務(wù)進(jìn)程(Service process)
4币叹、后臺(tái)進(jìn)程(Background process)
5润歉、空進(jìn)程(Empty process)
下面分別來(lái)闡述這五種進(jìn)程的特點(diǎn):
1、前臺(tái)進(jìn)程(Foreground process)
用戶(hù)當(dāng)前操作所必需的進(jìn)程套硼。在給定時(shí)間內(nèi)卡辰,前臺(tái)進(jìn)程同時(shí)存在的數(shù)量并不多。只有在內(nèi)存不足以支持它們同時(shí)存在時(shí)邪意,系統(tǒng)才會(huì)終止它們九妈。
前臺(tái)進(jìn)程的一些例子:
A、擁有用戶(hù)正在交互的Activity(已調(diào)用onResume)
B雾鬼、擁有某個(gè)Service萌朱,該Service和用戶(hù)正在交互的Activity綁定在一起。
C策菜、擁有正在“前臺(tái)”運(yùn)行的Service(服務(wù)已調(diào)用startForeground)
D晶疼、擁有正執(zhí)行一個(gè)生命周期回調(diào)的Service(onCreate、onStartCommand或者onDestroy)
E又憨、擁有正在執(zhí)行器onReceive方法的BroadcastReceiver

2翠霍、可見(jiàn)進(jìn)程(Visible process)
沒(méi)有任何前臺(tái)組件,但仍會(huì)影響用戶(hù)在屏幕上所見(jiàn)內(nèi)容的進(jìn)程蠢莺『祝可見(jiàn)進(jìn)程被視為極其重要的進(jìn)程,除非為了維持所有前臺(tái)進(jìn)程同時(shí)運(yùn)行而必須終止可見(jiàn)進(jìn)程躏将,否則是不會(huì)終止這些進(jìn)程的锄弱。
可見(jiàn)進(jìn)程的一些例子:
A考蕾、擁有不在前臺(tái),但仍對(duì)用戶(hù)可見(jiàn)的Activity(已調(diào)用onPause)
B会宪、擁有綁定到可見(jiàn)(或者前臺(tái))Activity的Service

3肖卧、服務(wù)進(jìn)程(Service process)
服務(wù)進(jìn)程與用戶(hù)所見(jiàn)內(nèi)容沒(méi)有直接的聯(lián)系,但是它們通常在執(zhí)行一些用戶(hù)關(guān)心的操作(例如掸鹅,在后臺(tái)播放音樂(lè)或從網(wǎng)絡(luò)下載數(shù)據(jù))塞帐。因此,除非內(nèi)存不足以維持所有前臺(tái)進(jìn)程和可見(jiàn)進(jìn)程同時(shí)運(yùn)行河劝,否則系統(tǒng)會(huì)讓服務(wù)進(jìn)程保持運(yùn)行狀態(tài)壁榕。
服務(wù)進(jìn)程的一些例子:
A、使用startService啟動(dòng)的服務(wù)赎瞎,并且不屬于上述兩個(gè)更高級(jí)別的進(jìn)程牌里。

4、后臺(tái)進(jìn)程(Background process)
后臺(tái)進(jìn)程對(duì)用戶(hù)體驗(yàn)沒(méi)有直接影響务甥,系統(tǒng)可能隨時(shí)終止它們牡辽,以回收內(nèi)存給前臺(tái)進(jìn)程、可見(jiàn)進(jìn)程和服務(wù)進(jìn)程敞临。通常會(huì)有很多后臺(tái)進(jìn)程在運(yùn)行态辛,因此它們會(huì)出現(xiàn)在LRU列表中,以確保包含用戶(hù)最近查看的Activity的進(jìn)程最后一個(gè)被終止挺尿。如果某個(gè)Activity正確實(shí)現(xiàn)了生命周期方法奏黑,并保存了其當(dāng)前狀態(tài),則終止其進(jìn)程不會(huì)對(duì)用戶(hù)體驗(yàn)產(chǎn)生明顯的影響编矾,因?yàn)楫?dāng)用導(dǎo)航回該Activity時(shí)熟史,Activity會(huì)恢復(fù)所有可見(jiàn)狀態(tài)。
后臺(tái)進(jìn)程的一些例子:
A窄俏、對(duì)用戶(hù)不可見(jiàn)的Activity的進(jìn)程(已調(diào)用Activity的onStop方法)

5蹂匹、空進(jìn)程(Empty process)
保留這種進(jìn)程的唯一目的是用作緩存,以縮短下次在其中運(yùn)行組件所需的啟動(dòng)時(shí)間凹蜈。為了總體系統(tǒng)資源在進(jìn)程緩存和底層內(nèi)核緩存之間保持平衡限寞,系統(tǒng)往往會(huì)終止這些進(jìn)程。
空進(jìn)程的一些例子:
A仰坦、不含任何活動(dòng)的應(yīng)用組件的進(jìn)程履植。

具體可以參考官方文檔的介紹:http://developer.android.com/intl/zh-cn/guide/components/processes-and-threads.html](http://developer.android.com/intl/zh-cn/guide/components/processes-and-threads.html

二、Android進(jìn)程回收策略

Android中內(nèi)存的回收悄晃,主要是由Lowmemorykiller來(lái)完成的静尼,它是一種根據(jù)OOM_ADJ閾值級(jí)別觸發(fā)相應(yīng)力度的內(nèi)存回收機(jī)制。

一般來(lái)說(shuō)传泊,OOM_ADJ為0代表的是前臺(tái)進(jìn)程鼠渺,大于0的表示一些后臺(tái)進(jìn)程或者是服務(wù)進(jìn)程。而OOM_ADJ小于0表示非Android進(jìn)程(純Linux進(jìn)程)眷细。
在Lowmemorykiller回收內(nèi)存時(shí)會(huì)根據(jù)進(jìn)程的級(jí)別優(yōu)先殺死OOM_ADJ比較大的進(jìn)程拦盹,而對(duì)于優(yōu)先級(jí)相同的進(jìn)程則優(yōu)先殺死那些占用內(nèi)存和存活時(shí)間比較大的進(jìn)程。

怎么查看進(jìn)程的優(yōu)先級(jí)(oom_adj的值)溪椎?
1普舆、在命令行模式下,使用adb shell命令進(jìn)入shell模式校读。
2沼侣、ps命令可以列舉出所有正在運(yùn)行的進(jìn)程的信息。當(dāng)然我們可以使用ps | grep 進(jìn)程名(一般為包名)來(lái)過(guò)濾得到我們想要的進(jìn)程歉秫。
3蛾洛、從第二步獲取進(jìn)程的id,然后使用 cat /proc/進(jìn)程id/oom_adj獲取該進(jìn)程的優(yōu)先級(jí)雁芙。
具體做法可以參考下面的例子:


查看進(jìn)程的優(yōu)先級(jí)

PS:查看進(jìn)程優(yōu)先級(jí)時(shí)轧膘,在第三步時(shí)會(huì)返回permission denied。那是因?yàn)闆](méi)有獲得手機(jī)的root權(quán)限兔甘,所以上述操作要在已root的手機(jī)或者模擬器上進(jìn)行谎碍。

綜上所述,為了減少進(jìn)程被殺的概率洞焙,則要想辦法提高進(jìn)程的優(yōu)先級(jí)蟆淀。接下來(lái)我們將從進(jìn)程優(yōu)先級(jí)的提升方面講一下幾種可行方案。

三澡匪、提升進(jìn)程優(yōu)先級(jí)的方案

1熔任、利用Activity提升進(jìn)程優(yōu)先級(jí)

1.1 方案設(shè)計(jì):
監(jiān)控手機(jī)的鎖屏和解鎖事件,在屏幕鎖屏?xí)r啟動(dòng)1個(gè)像素的Activity仙蛉,在解鎖時(shí)將Activity銷(xiāo)毀笋敞。該Activity要設(shè)計(jì)成用戶(hù)無(wú)感知。
這里有個(gè)前提是APP進(jìn)程需要在后臺(tái)荠瘪。如果APP進(jìn)程在前臺(tái)夯巷,那么進(jìn)程已經(jīng)是前臺(tái)進(jìn)程了,那么上面的做法就沒(méi)有任何意義了哀墓。

通過(guò)該方案趁餐,進(jìn)程的優(yōu)先級(jí)可以在鎖屏?xí)r由oom_adj為9(不同手機(jī)系統(tǒng)的值可能不一樣)提升到0(前臺(tái)進(jìn)程)。這樣我們的APP就不容易在鎖屏?xí)r間內(nèi)被第三方應(yīng)用給殺死篮绰。

1.2 適用范圍:
場(chǎng)景:該方案主要解決的痛點(diǎn)是第三方應(yīng)用或者系統(tǒng)管理工具會(huì)在檢測(cè)到鎖屏事件一段時(shí)間后殺死后臺(tái)進(jìn)程后雷,以達(dá)到省電的目的。

版本:適用于所有的Android版本。

1.3 具體實(shí)現(xiàn):
可參考Github上的開(kāi)源項(xiàng)目KeepProcessLive臀突。
對(duì)于該開(kāi)源項(xiàng)目勉抓,目前有一個(gè)疑問(wèn),在監(jiān)聽(tīng)手機(jī)的鎖屏解鎖事件時(shí)候学,會(huì)多次監(jiān)聽(tīng)到鎖屏藕筋、解鎖操作,導(dǎo)致有時(shí)候該方案無(wú)效梳码。

2隐圾、利用Notification提升進(jìn)程優(yōu)先級(jí)

2.1 方案設(shè)計(jì):
通過(guò)將Android中的Service的setForeground接口可以將后臺(tái)Service設(shè)置為前臺(tái)Service,這樣進(jìn)程的優(yōu)先級(jí)就被提升到了2掰茶,從而使進(jìn)程的優(yōu)先級(jí)僅僅次于用戶(hù)當(dāng)前正在交互的進(jìn)程暇藏,與可見(jiàn)進(jìn)程的優(yōu)先級(jí)一致,使進(jìn)程被殺死的概率大大降低濒蒋。

在A(yíng)ndroid 2.3開(kāi)始調(diào)用setForeground將后臺(tái)Service設(shè)置為前臺(tái)Service時(shí)盐碱,必須在系統(tǒng)的通知欄發(fā)送一條通知,這意味著前臺(tái)Service與一條可見(jiàn)的通知是綁定在一起的啊胶。但是對(duì)于不需要使用常駐通知欄的應(yīng)用來(lái)說(shuō)甸各,該方案是用戶(hù)感知的,沒(méi)有辦法直接使用焰坪。

我們可以通過(guò)實(shí)現(xiàn)一個(gè)內(nèi)部Service趣倾,在LiveService和其內(nèi)部Service中同時(shí)發(fā)送具有相同ID的Notification,然后將內(nèi)部Service結(jié)束掉某饰,同時(shí)也將Notification結(jié)束掉儒恋,隨著Notification的消失,用戶(hù)就無(wú)感知了黔漂,同時(shí)也實(shí)現(xiàn)了將系統(tǒng)優(yōu)先級(jí)提升到2的操作诫尽。

2.2 適用范圍:
版本:適用于所有的Android版本。

2.3 具體實(shí)現(xiàn):
可參考Github上的開(kāi)源項(xiàng)目KeepProcessLive炬守。

四牧嫉、進(jìn)程被殺后的拉活方案

1、利用系統(tǒng)廣播拉活

1.1 方案設(shè)計(jì):
在發(fā)生特定系統(tǒng)事件時(shí)减途,系統(tǒng)會(huì)發(fā)出響應(yīng)的廣播酣藻,如果我們?cè)贏(yíng)ndroidManifest中“靜態(tài)”注冊(cè)對(duì)應(yīng)的廣播監(jiān)聽(tīng)器,就可以在發(fā)生響應(yīng)事件時(shí)進(jìn)行拉活鳍置。
常用的用于拉活的廣播事件包括:

1.2 適用范圍:
適用于全部的Android平臺(tái)辽剧。但是存在著以下幾個(gè)缺點(diǎn):
1、廣播接收器被管理軟件或者系統(tǒng)軟件通過(guò)“自啟動(dòng)”等功能禁用的場(chǎng)景無(wú)法接收到廣播税产,從而無(wú)法自啟怕轿。
2偷崩、系統(tǒng)廣播事件是不可控制的,只能在保證發(fā)生廣播事件時(shí)拉活進(jìn)程撞羽,但是無(wú)法做到進(jìn)程掛掉后立即拉活阐斜。

因此,該方案只是作為一個(gè)備選方案放吩。

2智听、利用第三方應(yīng)用廣播拉活

2.1 方案設(shè)計(jì):
該方案的設(shè)計(jì)思想和接收系統(tǒng)廣播的類(lèi)似,不同的是該方案接收的是第三方Top應(yīng)用的廣播渡紫。

通過(guò)反編譯第三方Top應(yīng)用,如:手機(jī)QQ考赛、微信惕澎、支付寶、UC瀏覽器等颜骤,以及友盟唧喉、信鴿、個(gè)推等SDK忍抽,找出它們外發(fā)的廣播八孝,在應(yīng)用中進(jìn)行監(jiān)聽(tīng),當(dāng)這些應(yīng)用發(fā)出廣播時(shí)鸠项,就會(huì)將我們的應(yīng)用進(jìn)行拉活干跛。

2.2 適用范圍:
該方案的缺點(diǎn)和上面所說(shuō)的系統(tǒng)廣播的方案一樣之外,還有下面幾個(gè)缺點(diǎn):
1祟绊、進(jìn)程拉活的效果取決于反編譯分析過(guò)的第三方應(yīng)用的多少楼入。
2、第三方應(yīng)用的廣播屬于應(yīng)用私有的牧抽,所以有可能存在當(dāng)前版本有效的廣播在后續(xù)的版本中隨時(shí)有可能被移除或者被改為不外發(fā)嘉熊。

因此,該方案也只是作為一個(gè)備選方案扬舒。

3阐肤、利用系統(tǒng)Service機(jī)制拉活

3.1 方案設(shè)計(jì):
該方案將Service的onStartCommand方法的返回值設(shè)置為START_STICKY,利用系統(tǒng)機(jī)制在Service掛掉后自動(dòng)拉活讲坎。

3.2 適用范圍:
下面這兩種情況無(wú)法進(jìn)行拉活:
1孕惜、Service在第一次被異常殺死后會(huì)在5秒內(nèi)重啟,第二次被殺死后會(huì)在10秒重啟衣赶,第三次殺死后會(huì)在20秒重啟诊赊,但是一旦在短時(shí)間內(nèi)Service被殺死的次數(shù)達(dá)到5次,則系統(tǒng)不再拉起府瞄。
2碧磅、進(jìn)程被取得Root權(quán)限的管理工具或系統(tǒng)工具通過(guò)foreStop停止掉碘箍,則無(wú)法重啟。

4鲸郊、利用JobScheduler機(jī)制拉活

4.1 方案設(shè)計(jì):
Android 5.0以后的版本提供了JobScheduler接口丰榴,系統(tǒng)會(huì)定時(shí)調(diào)用該進(jìn)程以使應(yīng)用進(jìn)行一些邏輯操作。

4.2 適用范圍:
主要適用于A(yíng)ndroid 5.0以上的版本秆撮。在A(yíng)ndroid 5.0以上版本中不受forcestop影響四濒,被強(qiáng)制停止的應(yīng)用依然可以被拉起赎线,在A(yíng)ndroid 5.0以上版本拉活效果是非常好的你画。(但是在小米手機(jī)上可能會(huì)偶爾出現(xiàn)無(wú)法拉活的問(wèn)題。)

4.3 具體實(shí)現(xiàn):
可參考Github上的開(kāi)源項(xiàng)目KeepProcessLive预柒。

5舒裤、利用賬號(hào)同步機(jī)制拉活

5.1 方案設(shè)計(jì):
Android系統(tǒng)的賬號(hào)同步機(jī)制會(huì)定期同步賬號(hào)喳资,該方案的目的在于利用同步機(jī)制進(jìn)行進(jìn)程的拉活。

5.2 適用范圍:
適用于所有的Android版本腾供,包括forestop掉的進(jìn)程也可以進(jìn)行拉活仆邓。但是在最新Android版本(Android N)中系統(tǒng)好像對(duì)賬戶(hù)同步做了改動(dòng),所以該方法是否能夠再用還需要進(jìn)行一定的實(shí)驗(yàn)伴鳖。

五节值、參考文章

【騰訊Bugly干貨分享】Android進(jìn)程保活招式大全

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末榜聂,一起剝皮案震驚了整個(gè)濱河市搞疗,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌峻汉,老刑警劉巖贴汪,帶你破解...
    沈念sama閱讀 219,188評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異休吠,居然都是意外死亡扳埂,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,464評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén)瘤礁,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)阳懂,“玉大人,你說(shuō)我怎么就攤上這事柜思⊙业鳎” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,562評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵赡盘,是天一觀(guān)的道長(zhǎng)号枕。 經(jīng)常有香客問(wèn)我,道長(zhǎng)陨享,這世上最難降的妖魔是什么葱淳? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,893評(píng)論 1 295
  • 正文 為了忘掉前任钝腺,我火速辦了婚禮,結(jié)果婚禮上赞厕,老公的妹妹穿的比我還像新娘艳狐。我一直安慰自己,他們只是感情好皿桑,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,917評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布毫目。 她就那樣靜靜地躺著,像睡著了一般诲侮。 火紅的嫁衣襯著肌膚如雪镀虐。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,708評(píng)論 1 305
  • 那天浆西,我揣著相機(jī)與錄音粉私,去河邊找鬼。 笑死近零,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的抄肖。 我是一名探鬼主播久信,決...
    沈念sama閱讀 40,430評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼漓摩!你這毒婦竟也來(lái)了裙士?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,342評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤管毙,失蹤者是張志新(化名)和其女友劉穎腿椎,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體夭咬,經(jīng)...
    沈念sama閱讀 45,801評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡啃炸,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,976評(píng)論 3 337
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了卓舵。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片南用。...
    茶點(diǎn)故事閱讀 40,115評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖掏湾,靈堂內(nèi)的尸體忽然破棺而出裹虫,到底是詐尸還是另有隱情,我是刑警寧澤融击,帶...
    沈念sama閱讀 35,804評(píng)論 5 346
  • 正文 年R本政府宣布筑公,位于F島的核電站,受9級(jí)特大地震影響尊浪,放射性物質(zhì)發(fā)生泄漏匣屡。R本人自食惡果不足惜封救,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,458評(píng)論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望耸采。 院中可真熱鬧兴泥,春花似錦、人聲如沸虾宇。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,008評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至稀轨,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間奋刽,已是汗流浹背艰赞。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,135評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留方妖,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,365評(píng)論 3 373
  • 正文 我出身青樓雌澄,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親杯瞻。 傳聞我的和親對(duì)象是個(gè)殘疾皇子镐牺,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,055評(píng)論 2 355

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

  • 如何進(jìn)行進(jìn)程比喂瘢活,首先我們應(yīng)該先分析一下進(jìn)程被殺死的原因開(kāi)始 Android進(jìn)程被殺死的場(chǎng)景分析: 從 Andro...
    編程小豬閱讀 3,533評(píng)論 1 14
  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,180評(píng)論 25 707
  • 如何進(jìn)行進(jìn)程保活逆皮,首先我們應(yīng)該先分析一下進(jìn)程被殺死的原因開(kāi)始 Android進(jìn)程被殺死的場(chǎng)景分析: 從 Andro...
    如穎隨行日記閱讀 4,914評(píng)論 2 4
  • 最初對(duì)耐克的籃球鞋了解是我初二那年宅粥,十四歲的我僅僅知道我崇拜的球星的專(zhuān)注球鞋標(biāo)志是一個(gè)劍鞘,它讓我如此癡迷电谣』嗝罚可是由...
    Kanip閱讀 715評(píng)論 8 7
  • 沉靜的塘兒抹蚀, 小荷偷偷地探出腦袋。 那是我的思念企垦,悄悄地 發(fā)了芽环壤。
    湍河故事閱讀 256評(píng)論 0 1