Android開發(fā)套路# 線程和軟件開發(fā)

熟練使用Android上的線程可以幫助你提高應(yīng)用程序的性能。本文討論使用線程的幾個(gè)方面:使用UI或主線程、應(yīng)用程序生命周期與線程優(yōu)先級(jí)之間的關(guān)系册赛、以及平臺(tái)提供的幫助管理線程復(fù)雜性的方法门怪。

主線程

當(dāng)用戶啟動(dòng)你的應(yīng)用程序時(shí),Android會(huì)創(chuàng)建一個(gè)新的Linux進(jìn)程以及一個(gè)執(zhí)行線程罚勾。這個(gè)主線程, 也被稱為UI線程吭狡,負(fù)責(zé)屏幕上發(fā)生的所有事情尖殃。了解它如何工作可以幫助您設(shè)計(jì)您的應(yīng)用程序使用主線程以獲得最佳性能。

主線程的設(shè)計(jì)非常簡(jiǎn)單:它唯一的工作就是從線程安全的工作隊(duì)列中取出并執(zhí)行工作塊划煮,直到其應(yīng)用程序終止送丰。該框架從各個(gè)地方生成了這些工作的一部分。這些地方包括與生命周期信息相關(guān)的回調(diào)弛秋,用戶事件(如輸入)或來自其他應(yīng)用程序和進(jìn)程的事件器躏。此外,應(yīng)用程序可以自己明確排隊(duì)蟹略,而無需使用框架登失。

應(yīng)用程序 幾乎執(zhí)行任何代碼塊都與事件回調(diào)有關(guān),例如輸入挖炬,布局膨脹或繪制揽浙。當(dāng)事件觸發(fā)事件時(shí),事件發(fā)生的線程將事件推出自身意敛,并進(jìn)入主線程的消息隊(duì)列馅巷。主線程可以為事件提供服務(wù)。

當(dāng)動(dòng)畫或畫面更新發(fā)生時(shí)空闲,系統(tǒng)每隔16ms左右嘗試執(zhí)行一個(gè)工作塊(負(fù)責(zé)繪制畫面)令杈,以便以每秒60幀的速度平滑地進(jìn)行渲染。為了達(dá)到這個(gè)目標(biāo)碴倾,UI / View層次結(jié)構(gòu)必須在主線程上更新逗噩。但是,當(dāng)主線程的消息傳遞隊(duì)列包含的任務(wù)太多或太長(zhǎng)時(shí)跌榔,主線程無法完成足夠快的更新時(shí)异雁,應(yīng)用程序應(yīng)將此工作移至工作線程。如果主線程無法在16ms內(nèi)完成工作塊僧须,用戶可能會(huì)觀察到拖尾纲刀,或者對(duì)輸入的UI響應(yīng)性不足。如果主線程阻塞大約五秒鐘担平,則系統(tǒng)顯示應(yīng)用程序不響應(yīng) (ANR)對(duì)話框示绊,允許用戶直接關(guān)閉應(yīng)用程序锭部。

從主線程中移動(dòng)大量或長(zhǎng)時(shí)間的任務(wù),以避免影響用戶輸入的平滑呈現(xiàn)和快速響應(yīng)面褐,是您在應(yīng)用中采用線程的最大原因拌禾。

線程和UI對(duì)象引用

按照設(shè)計(jì),Android視圖對(duì)象不是線程安全的展哭。預(yù)計(jì)應(yīng)用程序?qū)⒃谥骶€程上創(chuàng)建湃窍,使用和銷毀UI對(duì)象。如果你嘗試修改甚至引用主線程以外的線程中的UI對(duì)象匪傍,則結(jié)果可能是異常您市,將無提示失敗、崩潰以及其他未定義的錯(cuò)誤行為役衡。

引用的問題分為兩個(gè)不同的類別:顯式引用隱式引用茵休。

顯式引用

非主線程上的許多任務(wù)都有更新UI對(duì)象的最終目標(biāo)。但是手蝎,如果其中一個(gè)線程訪問視圖層次結(jié)構(gòu)中的對(duì)象泽篮,則可能導(dǎo)致應(yīng)用程序不穩(wěn)定:如果工作線程在任何其他線程正在引用該對(duì)象的同時(shí)更改該對(duì)象的屬性,則結(jié)果是未定義的柑船。

例如,考慮在工作線程上保存對(duì)UI對(duì)象的直接引用的應(yīng)用程序泼各。工作線程上的對(duì)象可能包含對(duì)a的引用 View; 但在工作完成之前鞍时,View將從視圖層次結(jié)構(gòu)中移除。當(dāng)這兩個(gè)動(dòng)作同時(shí)發(fā)生時(shí)扣蜻,引用將View對(duì)象保存在內(nèi)存中并在其上設(shè)置屬性逆巍。但是,用戶從不會(huì)看到這個(gè)對(duì)象莽使,并且一旦對(duì)象的引用消失锐极,該應(yīng)用程序就會(huì)刪除該對(duì)象。

在另一個(gè)例子中芳肌,View對(duì)象包含對(duì)擁有它們的活動(dòng)的引用灵再。如果這個(gè)活動(dòng)被破壞了,但是仍有一個(gè)直接或間接引用它的線程塊亿笤,那么垃圾收集器將不會(huì)收集這個(gè)活動(dòng)翎迁,直到這個(gè)工作塊完成執(zhí)行。

在發(fā)生線程工作的情況下净薛,如果發(fā)生某個(gè)活動(dòng)生命周期事件(如屏幕旋轉(zhuǎn))汪榔,此情形可能會(huì)導(dǎo)致出現(xiàn)問題。系統(tǒng)將無法執(zhí)行垃圾收集肃拜,直到正在進(jìn)行的工作完成痴腌。因此雌团,Activity在垃圾收集發(fā)生之前,內(nèi)存中可能有兩個(gè)對(duì)象士聪。

通過這樣的場(chǎng)景锦援,我們建議您的應(yīng)用程序不要在線程工作任務(wù)中包含對(duì)UI對(duì)象的顯式引用。避免這種引用可以幫助您避免這些類型的內(nèi)存泄漏戚嗅,同時(shí)避免線程爭(zhēng)用雨涛。

在所有情況下,您的應(yīng)用程序只應(yīng)更新主線程上的UI對(duì)象懦胞。這意味著您應(yīng)該制定一個(gè)協(xié)商策略替久,允許多個(gè)線程將工作交流回主線程,主線程將更新實(shí)際UI對(duì)象的工作作為最高活動(dòng)或片段躏尉。

隱式引用

在下面的代碼片段中可以看到一個(gè)帶有線程對(duì)象的常見代碼設(shè)計(jì)缺陷:

public class MainActivity extends Activity {
  // …...
  public class MyAsyncTask extends AsyncTask<Void, Void, String>   {
    @Override protected String doInBackground(Void... params) {...}
    @Override protected void onPostExecute(String result) {...}
  }
}

這段代碼中的缺陷是代碼將線程對(duì)象聲明MyAsyncTask為一些活動(dòng)的非靜態(tài)內(nèi)部類蚯根。這個(gè)聲明創(chuàng)建了一個(gè)對(duì)包含Activity實(shí)例的隱式引用。因此胀糜,該對(duì)象包含對(duì)該活動(dòng)的引用颅拦,直到線程工作完成,從而導(dǎo)致引用活動(dòng)的銷毀延遲教藻。這種延遲反過來又會(huì)增加內(nèi)存距帅。

直接解決這個(gè)問題的方法是將你的重載的類實(shí)例定義為靜態(tài)類,或者在它們自己的文件中去掉隱式引用括堤。

另一個(gè)解決方案是將AsyncTask對(duì)象聲明為靜態(tài)嵌套類碌秸。這樣做可以消除隱式引用問題,因?yàn)殪o態(tài)嵌套類不同于內(nèi)部類:內(nèi)部類的實(shí)例需要實(shí)例化外部類的實(shí)例悄窃,并且可以直接訪問它的封閉方法和字段實(shí)例讥电。相比之下,靜態(tài)嵌套類不需要引用包含類的實(shí)例轧抗,因此它不包含對(duì)外部類成員的引用恩敌。

public class MainActivity extends Activity {
  // …...
  static public class MyAsyncTask extends AsyncTask<Void, Void, String>   {
    @Override protected String doInBackground(Void... params) {...}
    @Override protected void onPostExecute(String result) {...}
  }
}

線程和應(yīng)用程序以及活動(dòng)生命周期

應(yīng)用程序生命周期可以影響線程在您的應(yīng)用程序中的工作方式。你可能需要決定一個(gè)線程應(yīng)該或不應(yīng)該在一個(gè)活動(dòng)被破壞之后持續(xù)下去横媚。你還應(yīng)該了解線程優(yōu)先級(jí)與活動(dòng)是在前臺(tái)還是在后臺(tái)運(yùn)行之間的關(guān)系纠炮。

持續(xù)執(zhí)行線程

線程一直持續(xù)到產(chǎn)生它們的活動(dòng)的生命周期。線程繼續(xù)執(zhí)行分唾,不受干擾抗碰,無論創(chuàng)建或破壞活動(dòng)。在某些情況下绽乔,這種持久性是可取的弧蝇。

考慮一種情況,其中一個(gè)活動(dòng)產(chǎn)生一組線程化的工作塊,然后在工作線程可以執(zhí)行塊之前被銷毀看疗。應(yīng)用程序應(yīng)該怎樣處理正在運(yùn)行的程序段沙峻?

如果塊要更新不再存在的用戶界面,則沒有理由繼續(xù)工作两芳。例如摔寨,如果工作是從數(shù)據(jù)庫加載用戶信息,然后更新視圖怖辆,則不再需要該線程是复。

相比之下,工作包可能有一些不完全與用戶界面相關(guān)的好處竖螃。在這種情況下淑廊,你應(yīng)該堅(jiān)持這個(gè)線程。例如特咆,數(shù)據(jù)包可能正在等待下載映像季惩,將其緩存到磁盤,并更新關(guān)聯(lián)的 View對(duì)象腻格。盡管該對(duì)象不再存在画拾,但是在用戶返回被銷毀的活動(dòng)的情況下,下載和緩存圖像的行為仍可能是有幫助的菜职。

手動(dòng)管理所有線程對(duì)象的生命周期響應(yīng)可能變得非常復(fù)雜青抛。如果你不正確地管理它們,你的應(yīng)用程序可能會(huì)遭受內(nèi)存爭(zhēng)用和性能問題酬核。裝載機(jī) 是解決這個(gè)問題的方法之一脂凶。加載程序有助于異步加載數(shù)據(jù),同時(shí)還可以通過配置更改來保存信息愁茁。

線程優(yōu)先級(jí)

“ 進(jìn)程和應(yīng)用程序生命周期”中所述,應(yīng)用程序線程獲得的優(yōu)先級(jí)部分取決于應(yīng)用程序生命周期中的應(yīng)用程序的位置亭病。在創(chuàng)建和管理應(yīng)用程序中的線程時(shí)鹅很,重要的是設(shè)置其優(yōu)先級(jí),以便正確的線程在正確的時(shí)間獲得正確的優(yōu)先級(jí)罪帖。如果設(shè)置得太高促煮,你的線程可能會(huì)中斷UI線程和RenderThread,導(dǎo)致你的應(yīng)用程序丟幀整袁。如果設(shè)置得太低菠齿,可以使你的異步任務(wù)(如圖像加載)比他們需要的慢。

每當(dāng)你創(chuàng)建一個(gè)線程坐昙,你應(yīng)該打電話 setThreadPriority()绳匀。系統(tǒng)的線程調(diào)度器優(yōu)先考慮高優(yōu)先級(jí)的線程,平衡這些優(yōu)先級(jí),最終完成所有工作疾棵。一般來說戈钢,前臺(tái)組中的線程占設(shè)備總執(zhí)行時(shí)間的95%左右,而后臺(tái)組大約占5%是尔。

系統(tǒng)還使用Process該類為每個(gè)線程分配自己的優(yōu)先級(jí)值 殉了。

默認(rèn)情況下,系統(tǒng)將線程的優(yōu)先級(jí)設(shè)置為與產(chǎn)卵線程相同的優(yōu)先級(jí)和組成員資格拟枚。但是薪铜,您的應(yīng)用程序可以使用明確調(diào)整線程優(yōu)先級(jí)
setThreadPriority()

你的應(yīng)用程序應(yīng)該將線程的優(yōu)先級(jí)設(shè)置為THREAD_PRIORITY_BACKGROUND為執(zhí)行不太緊急工作的線程恩溅。

你的應(yīng)用程序可以使用THREAD_PRIORITY_LESS_FAVORABLETHREAD_PRIORITY_MORE_FAVORABLE常量作為增量來設(shè)置相對(duì)優(yōu)先級(jí)隔箍。有關(guān)線程優(yōu)先級(jí)的列表,請(qǐng)參閱類中的THREAD_PRIORITY常量Process暴匠。

線程的helper類

Fragment提供了相同的Java類和基本類型鞍恢,以方便線程,比如Thread每窖,RunnableExecutors類帮掉。為了幫助減少與為Android開發(fā)線程應(yīng)用程序相關(guān)的認(rèn)知負(fù)載,框架提供了一系列可以幫助開發(fā)的幫助程序窒典,例如AsyncTaskLoaderAsyncTask蟆炊。每個(gè)輔助類都有一組特定的性能細(xì)微差別,這些細(xì)微差別使得它們對(duì)于特定的線程問題子集是唯一的瀑志。對(duì)錯(cuò)誤的情況使用錯(cuò)誤的類可能會(huì)導(dǎo)致性能問題涩搓。

AsyncTask類

本AsyncTask類是需要快速從主線程移動(dòng)工作到工作線程應(yīng)用程序的簡(jiǎn)單,實(shí)用的原始劈猪。例如昧甘,輸入事件可能觸發(fā)需要用加載的位圖更新UI。一個(gè)AsyncTask 對(duì)象可以卸載位圖加載和解碼到另一個(gè)線程; 一旦處理完成战得,AsyncTask對(duì)象可以管理接收主線程上的工作以更新UI充边。

使用時(shí)AsyncTask,要記住一些重要的性能方面常侦。首先浇冰,默認(rèn)情況下,一個(gè)應(yīng)用程序?qū)syncTask 其創(chuàng)建的所有對(duì)象推送到單個(gè)線程中聋亡。因此肘习,它們以串行方式執(zhí)行,并且與主線程一樣坡倔,特別長(zhǎng)的工作包可以阻塞隊(duì)列漂佩。因此脖含,我們建議您僅AsyncTask處理短于5ms的工作項(xiàng)目。

AsyncTask對(duì)象也是隱式引用問題的最常見的仅仆。 AsyncTask對(duì)象也存在與明確引用有關(guān)的風(fēng)險(xiǎn)器赞,但這些有時(shí)候更容易解決。例如墓拜,AsyncTask 為了正確地更新UI對(duì)象港柜,可能需要對(duì)UI對(duì)象的引用,一旦AsyncTask在主線程上執(zhí)行其回調(diào)咳榜。在這種情況下夏醉,您可以使用一個(gè)WeakReference來存儲(chǔ)對(duì)所需UI對(duì)象的引用,并AsyncTask在主線程上運(yùn)行時(shí)訪問該對(duì)象 涌韩。要清楚畔柔,持有一個(gè)WeakReference對(duì)象不會(huì)使對(duì)象線程安全; 在 WeakReference僅提供處理與明確提到和垃圾收集問題的方法。

HandlerThread類

雖然一個(gè)AsyncTask 是有用的臣樱, 它可能并不總是正確的解決你的線程問題靶擦。相反,您可能需要更傳統(tǒng)的方法來在較長(zhǎng)時(shí)間運(yùn)行的線程上執(zhí)行一個(gè)工作塊雇毫,以及手動(dòng)管理該工作流的能力玄捕。

考慮從Camera對(duì)象獲取PreviewFrame的常見挑戰(zhàn) 。當(dāng)你注冊(cè)攝像頭預(yù)覽幀時(shí)棚放,你會(huì)在onPreviewFrame()調(diào)中接收到這些回調(diào)枚粘,該回調(diào)將在調(diào)用它的事件線程上調(diào)用。如果在UI線程上調(diào)用此回調(diào)函數(shù)飘蚯,則處理巨大像素?cái)?shù)組的任務(wù)將干擾渲染和事件處理工作馍迄。同樣的問題也適用于AsyncTask連續(xù)執(zhí)行作業(yè),這容易被阻塞局骤。

這是一個(gè)處理程序線程適當(dāng)?shù)那闆r:處理程序線程實(shí)際上是一個(gè)長(zhǎng)時(shí)間運(yùn)行的線程攀圈,它從隊(duì)列中抓取工作,并對(duì)其進(jìn)行操作峦甩。在這個(gè)例子中量承,當(dāng)你的應(yīng)用程序把這個(gè)Camera.open()命令委托 給處理程序線程的一個(gè)工作塊時(shí),相關(guān)的onPreviewFrame()回調(diào)就落在處理程序線程上穴店,而不是UI或AsyncTask 線程上。所以拿穴,如果你要在像素上做長(zhǎng)時(shí)間的工作泣洞,這可能是一個(gè)更好的解決方案。

當(dāng)你的應(yīng)用程序創(chuàng)建一個(gè)使用的線程時(shí)HandlerThread默色,不要忘記 根據(jù)它所做的工作類型來設(shè)置線程的 優(yōu)先級(jí)球凰。請(qǐng)記住,CPU只能并行處理少量的線程。設(shè)置優(yōu)先級(jí)有助于系統(tǒng)知道正確的方式來安排這項(xiàng)工作呕诉,當(dāng)所有其他線程爭(zhēng)取注意缘厢。

ThreadPoolExecutor類

有一些類型的工作可以降低到高度并行的分布式任務(wù)。例如甩挫,一個(gè)這樣的任務(wù)是為一個(gè)8兆像素圖像的每個(gè)8×8塊計(jì)算濾波器贴硫。這個(gè)工作包的數(shù)量很大,而且不是合適的類別伊者。單線程本質(zhì)將把所有的線程化工作轉(zhuǎn)化為一個(gè)線性系統(tǒng)英遭。另一方面,使用這個(gè)類會(huì)要求程序員手動(dòng)管理一組線程之間的負(fù)載平衡亦渗。

ThreadPoolExecutor是一個(gè)輔助類挖诸,使這個(gè)過程更容易。這個(gè)類管理著一組線程的創(chuàng)建法精,設(shè)置它們的優(yōu)先級(jí)多律,并管理這些線程之間的工作分配方式。隨著工作量的增加或減少搂蜓,這個(gè)類會(huì)加速或破壞更多的線程以適應(yīng)工作負(fù)載狼荞。

這個(gè)類也可以幫助你的應(yīng)用產(chǎn)生最佳的線程數(shù)量。當(dāng)它構(gòu)造一個(gè)ThreadPoolExecutor對(duì)象時(shí)洛勉,應(yīng)用程序設(shè)置最小和最大線程數(shù)粘秆。由于ThreadPoolExecutor增加的工作量 ,班級(jí)將考慮初始化的最小和最大線程數(shù)收毫,并考慮待處理的工作量攻走。基于這些因素此再,ThreadPoolExecutor決定在任何給定時(shí)間應(yīng)該有多少線程活著昔搂。

你應(yīng)該創(chuàng)建多少個(gè)線程?

盡管從軟件級(jí)別來看,你的代碼有能力創(chuàng)建數(shù)百個(gè)線程输拇,但這樣做會(huì)造成性能問題摘符。你的應(yīng)用程序與后臺(tái)服務(wù),渲染器策吠,音頻引擎逛裤,網(wǎng)絡(luò)等共享有限的CPU資源。CPU實(shí)際上只能并行處理少量的線程猴抹,上面的所有內(nèi)容都會(huì)遇到 優(yōu)先級(jí)和調(diào)度問題带族。因此,只需創(chuàng)建與您的工作負(fù)載所需的線程數(shù)量就很重要蟀给。

實(shí)際上蝙砌,有很多變量對(duì)此負(fù)責(zé)阳堕,但是選擇一個(gè)值(比如4,對(duì)于初學(xué)者)择克,并且使用Systrace進(jìn)行測(cè)試與 其他方法一樣可靠恬总。你可以使用反復(fù)試驗(yàn)來發(fā)現(xiàn)可以使用的最少線程數(shù)量,而不會(huì)遇到問題肚邢。

決定有多少線程的另一個(gè)考慮因素是線程不是免費(fèi)的:它們占用內(nèi)存壹堰。每個(gè)線程最少需要64k的內(nèi)存。這在設(shè)備上安裝的許多應(yīng)用程序中快速增加道偷,尤其是在調(diào)用堆棧顯著增長(zhǎng)的情況下缀旁。

許多系統(tǒng)進(jìn)程和第三方庫經(jīng)常會(huì)啟動(dòng)自己的線程池。如果你的應(yīng)用程序可以重復(fù)使用現(xiàn)有的線程池勺鸦,則這種重用可以通過減少內(nèi)存和處理資源的爭(zhēng)用來幫助提高性能并巍。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市换途,隨后出現(xiàn)的幾起案子懊渡,更是在濱河造成了極大的恐慌,老刑警劉巖军拟,帶你破解...
    沈念sama閱讀 206,214評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件剃执,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡懈息,警方通過查閱死者的電腦和手機(jī)肾档,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,307評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來辫继,“玉大人怒见,你說我怎么就攤上這事」每恚” “怎么了遣耍?”我有些...
    開封第一講書人閱讀 152,543評(píng)論 0 341
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)炮车。 經(jīng)常有香客問我舵变,道長(zhǎng),這世上最難降的妖魔是什么瘦穆? 我笑而不...
    開封第一講書人閱讀 55,221評(píng)論 1 279
  • 正文 為了忘掉前任纪隙,我火速辦了婚禮,結(jié)果婚禮上扛或,老公的妹妹穿的比我還像新娘绵咱。我一直安慰自己,他們只是感情好告喊,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,224評(píng)論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般则剃。 火紅的嫁衣襯著肌膚如雪巾兆。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,007評(píng)論 1 284
  • 那天秆吵,我揣著相機(jī)與錄音淮椰,去河邊找鬼。 笑死纳寂,一個(gè)胖子當(dāng)著我的面吹牛主穗,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播毙芜,決...
    沈念sama閱讀 38,313評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼忽媒,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了腋粥?” 一聲冷哼從身側(cè)響起晦雨,我...
    開封第一講書人閱讀 36,956評(píng)論 0 259
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎隘冲,沒想到半個(gè)月后闹瞧,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,441評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡展辞,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,925評(píng)論 2 323
  • 正文 我和宋清朗相戀三年奥邮,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片罗珍。...
    茶點(diǎn)故事閱讀 38,018評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡洽腺,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出靡砌,到底是詐尸還是另有隱情已脓,我是刑警寧澤,帶...
    沈念sama閱讀 33,685評(píng)論 4 322
  • 正文 年R本政府宣布通殃,位于F島的核電站度液,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏画舌。R本人自食惡果不足惜堕担,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,234評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望曲聂。 院中可真熱鬧霹购,春花似錦、人聲如沸朋腋。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,240評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至贞奋,卻和暖如春赌厅,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背轿塔。 一陣腳步聲響...
    開封第一講書人閱讀 31,464評(píng)論 1 261
  • 我被黑心中介騙來泰國打工特愿, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人勾缭。 一個(gè)月前我還...
    沈念sama閱讀 45,467評(píng)論 2 352
  • 正文 我出身青樓揍障,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國和親俩由。 傳聞我的和親對(duì)象是個(gè)殘疾皇子毒嫡,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,762評(píng)論 2 345

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

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 171,501評(píng)論 25 707
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn)采驻,斷路器审胚,智...
    卡卡羅2017閱讀 134,599評(píng)論 18 139
  • java 接口的意義-百度 規(guī)范、擴(kuò)展礼旅、回調(diào) 抽象類的意義-樂視 為其子類提供一個(gè)公共的類型封裝子類中得重復(fù)內(nèi)容定...
    交流電1582閱讀 2,209評(píng)論 0 11
  • 當(dāng)某個(gè)應(yīng)用組件啟動(dòng)且該應(yīng)用沒有運(yùn)行其他任何組件時(shí)膳叨,Android 系統(tǒng)會(huì)使用單個(gè)執(zhí)行線程為應(yīng)用啟動(dòng)新的 Linux...
    小蕓論閱讀 1,674評(píng)論 0 12
  • 不愿意收拾,從八月到今天痘系,從作出離開上海的決定到現(xiàn)在菲嘴,經(jīng)歷了一個(gè)季度之長(zhǎng),卻人動(dòng)汰翠,心不愿意動(dòng)龄坪。 今早起來,突...
    彩繪閱讀 236評(píng)論 0 0