春招筆記(十七)--安卓第七部分

1.線程進(jìn)程

默認(rèn)情況下,一個(gè)應(yīng)用分配一個(gè)進(jìn)程,同一應(yīng)用的所有組件都在相同的進(jìn)程和線程中運(yùn)行。

四大組件可以通過(guò)設(shè)置 android:proccess 指定組件運(yùn)行的線程,application 也支持 android:proccess 屬性,以設(shè)置所有組件的默認(rèn)值。

通過(guò)設(shè)置 android:process 可以使不同應(yīng)用的組件在同一進(jìn)程中運(yùn)行,這些應(yīng)用享有相同的Linux UserID( android:sharedUserId屬性)和證書(shū)簽名。

Android為每個(gè)安裝好的應(yīng)用程序分配了自己的UID,故進(jìn)程的UID是鑒別進(jìn)程身份的重要標(biāo)志。

系統(tǒng)內(nèi)存不足時(shí),系統(tǒng)會(huì)選擇相對(duì)不重要的進(jìn)程殺死,其優(yōu)先級(jí)如下:

前臺(tái)進(jìn)程

正在交互的Activity(已調(diào)用Activity的onResume)

正在交互的Activity綁定的Service

前臺(tái)運(yùn)行的Sercive(Service調(diào)用startForeground)

正在執(zhí)行生命周期方法的Service(onCreate,onStart或onDestory)

正在執(zhí)行onReceive()的BroadcastReceiver

可見(jiàn)進(jìn)程 沒(méi)有任何前臺(tái)組件,但仍然能被用戶(hù)看到內(nèi)容的進(jìn)程。

調(diào)用 onPause 方法的Activity(例如前臺(tái)組件部分透明,允許顯示下一層的Activity)。

調(diào)用 onPause 方法的Activity綁定的Service。

服務(wù)進(jìn)程

正在運(yùn)行已使用 startService() 方法啟動(dòng)的服務(wù)且不屬于上述兩個(gè)更高類(lèi)別進(jìn)程的進(jìn)程(例如,在后臺(tái)播放音樂(lè)或從網(wǎng)絡(luò)下載數(shù)據(jù))。

后臺(tái)進(jìn)程 已經(jīng)執(zhí)行onStop的Activity。這些進(jìn)程會(huì)被放在LRU列表中,以確保用戶(hù)最近查看最后一個(gè)被終止。

空進(jìn)程 不含任何應(yīng)用組件的進(jìn)程。保留這種進(jìn)程的的唯一目的是用作緩存,以縮短下次在其中運(yùn)行組件所需的啟動(dòng)時(shí)間。

因此耗時(shí)操作的Activity最好為該耗時(shí)操作啟動(dòng)服務(wù)而不是創(chuàng)建線程。例如:正在上傳圖片的Activity啟動(dòng)服務(wù)來(lái)上傳,這樣即使用戶(hù)推出Activity,操作仍然可以在后臺(tái)進(jìn)行。

線程安全

當(dāng)某些方法可能會(huì)從多個(gè)線程調(diào)用時(shí),編寫(xiě)時(shí)必須考慮線程安全。

Binder方法的調(diào)用方如果在同一進(jìn)程,則該方法在調(diào)用方的線程執(zhí)行。

Binder方法的調(diào)用方如果不在同一進(jìn)程,方法將在線程池(Binder所在的進(jìn)程維護(hù))中被調(diào)用,即使調(diào)用方是在UI線程中執(zhí)行,Binder方法依然會(huì)被在線程池中執(zhí)行后返回。

可能會(huì)有多個(gè)池線程在同一時(shí)間使用Binder方法。因此,Binder 方法必須實(shí)現(xiàn)為線程安全方法。

同理ContentProvider的增刪改查方法也是在進(jìn)程的線程池中調(diào)用,而不是在UI線程。由于這些方法可能會(huì)同時(shí)從任意數(shù)量的線程調(diào)用,因此它們也必須實(shí)現(xiàn)為線程安全方法。


2.IPC

多進(jìn)程模式

進(jìn)程間通信(IPC,Inter-Process Communication),指至少兩個(gè)進(jìn)程或線程間傳送數(shù)據(jù)或信號(hào)的一些技術(shù)或方法。

通過(guò)給四大組件指定 android:proccess 屬性,只有這一種方法可以正常開(kāi)啟多進(jìn)程模式。

多進(jìn)程模式中,不同進(jìn)程的組件會(huì)擁有獨(dú)立的虛擬機(jī),Application,內(nèi)存。

通過(guò)JNI在native層中fork一個(gè)新的進(jìn)程,是不常用的創(chuàng)建多線程的方法。

入口Activity如果不指定process屬性,那么它運(yùn)行在默認(rèn)進(jìn)程中,默認(rèn)進(jìn)程的進(jìn)程名是包名,例如android:process=":"。

:的含義是指要在當(dāng)前的進(jìn)程名前附加上當(dāng)前的包名。com.xxx.text:remote == :remote。

進(jìn)程名以:開(kāi)頭的屬于私有進(jìn)程。而進(jìn)程名不以:開(kāi)頭的屬于全局進(jìn)程,其他應(yīng)用可以通過(guò)ShareUID和她跑在統(tǒng)一進(jìn)程中。

Android為每個(gè)進(jìn)程都分配了一個(gè)虛擬機(jī),不同的虛擬機(jī)訪問(wèn)同一個(gè)對(duì)象會(huì)產(chǎn)生多份副本,導(dǎo)致數(shù)據(jù)不一致,所以需要IPC。

3.序列化

Serializable 和 Pracelable 接口可以完成對(duì)象的序列化。

Serializable是JAVA提供的序列化接口,只需要在類(lèi)中聲明serialVersionUID,即可自動(dòng)實(shí)現(xiàn)默認(rèn)的序列化過(guò)程。

對(duì)象序列化只要使用ObjectOutputStream和ObjectInputStream即可。

如果不手動(dòng)指定serialVersionUID,反序列化時(shí)類(lèi)有所改變,將導(dǎo)致crash。

靜態(tài)成員變量不屬于對(duì)象,所以不參與序列化。

用transient關(guān)鍵字編輯的成員變量不參與序列化過(guò)程,用來(lái)修飾無(wú)意義的不用序列化的變量。

Serializable 系統(tǒng)默認(rèn)的序列化過(guò)程也是可以改變的,重寫(xiě)writeObject和readObject即可。

系統(tǒng)已經(jīng)為我們提供了許多實(shí)現(xiàn)Parcelable接口的類(lèi),是可以直接序列化的,Intent,Bundle,Bitmap等。List和Map也可以序列化,前提是他們里面的類(lèi)都是可序列化的。

使用Parcelable需要重寫(xiě)指定方法。

Serializable是JAVA中的序列化接口,使用簡(jiǎn)單但開(kāi)銷(xiāo)巨大,序列化個(gè)反序列化需要進(jìn)行大量I/O操作;Parcelable是Android中的序列化方式,使用麻煩但是效率高,Android推薦。

Parcelable主要用在內(nèi)存序列化上(intent傳遞)。將對(duì)象序列化到存儲(chǔ)設(shè)備或序列化后網(wǎng)絡(luò)傳輸通過(guò)Parcelable會(huì)稍顯復(fù)雜,這兩種情況建議使用Serializable。

4.Binder連接池

多個(gè)不同的業(yè)務(wù)模塊需要使用AIDL進(jìn)行進(jìn)程間通訊,為了減少Service的數(shù)量,將所有的AIDL放在同一個(gè)Service中進(jìn)行管理。

各個(gè)模塊像服務(wù)端提供自己的唯一標(biāo)識(shí)和與其對(duì)應(yīng)的Binder對(duì)象;服務(wù)端至于要一個(gè)Service,然后提供一個(gè)queryBinder接口,這個(gè)接口根據(jù)相應(yīng)的模塊來(lái)返回對(duì)應(yīng)的Binder。

5.Socket

Socket也稱(chēng)套接字,是網(wǎng)絡(luò)通信中的概念。

分為流式套接字和用戶(hù)數(shù)據(jù)報(bào)套接字,對(duì)應(yīng)網(wǎng)絡(luò)傳輸控制層中的TCP和UDP協(xié)議。

TCP面向連接的協(xié)議,提供穩(wěn)定的雙向通信功能。經(jīng)過(guò)三次握手才能完成,自身提供超時(shí)重傳機(jī)制,穩(wěn)定性強(qiáng)。

UDP是面向過(guò)程,無(wú)連接的,提供不穩(wěn)定的單向通訊,當(dāng)然也可以實(shí)現(xiàn)雙向。UDP有較好的性能,缺點(diǎn)是穩(wěn)定性不強(qiáng)。

Socket的使用:

在配置文件中聲明網(wǎng)絡(luò)訪問(wèn)的權(quán)限(不能在主線程中訪問(wèn)網(wǎng)絡(luò))。

遠(yuǎn)程Service建立一個(gè)TCP服務(wù)(通過(guò)ServerSocket對(duì)象),然后在主界面中連接TCP服務(wù)。

重連機(jī)制:每次連接失敗后嘗試重新建立連接,為了降低重試機(jī)制的開(kāi)銷(xiāo),加入休眠機(jī)制,即線程休眠1000毫秒。

Activity退出時(shí)(OnDestory),需要關(guān)閉Socket。

Socket可以實(shí)現(xiàn)進(jìn)程間通訊,也可以實(shí)現(xiàn)設(shè)備間通信,前提是設(shè)備之間的IP地址互相可見(jiàn)。

6.ContentProvider

ContentProvider底層實(shí)現(xiàn)也是Binder。

ContentProvider進(jìn)程中,除了onCreat由系統(tǒng)回調(diào)并運(yùn)行在主線程里,其他五個(gè)方法均有外界回調(diào)發(fā)生在Binder線程池中。

雖然ContentProvider的底層數(shù)據(jù)看起來(lái)像SQLLite數(shù)據(jù)庫(kù),其實(shí)它對(duì)底層數(shù)據(jù)的數(shù)據(jù)沒(méi)有任何要求。

ContentProvider還支持文件數(shù)據(jù),比如圖片視頻表格等,處理這類(lèi)數(shù)據(jù)時(shí)可以在ContentProvider返回文件的句柄給外界從而讓文件來(lái)訪問(wèn)ContentProvider中的文件信息。

Android系統(tǒng)所提供的MediaStore功能就是文件類(lèi)型的ContentProvider。

ContentProvider的使用:

聲明時(shí),android:authorities 是唯一標(biāo)識(shí),建議命名時(shí)加上包名前綴。而且可以通過(guò)控制permission來(lái)控制外界訪問(wèn)的權(quán)限。

ContentProvider的三次query方法可能運(yùn)行在三個(gè)不同的線程中,一個(gè)Binder線程池中。

除了query方法,update,delete,insert方法會(huì)引起數(shù)據(jù)源的改變,可以通過(guò)注冊(cè)registerContentResever來(lái)注冊(cè)觀察者,unregister解除觀察者。通過(guò)ContentResever的notifyChange通知外界數(shù)據(jù)已經(jīng)改變。

增刪改查是存在多線程并發(fā)的,因此方法內(nèi)部需要做好線程同步。比如只使用一個(gè)SQLite對(duì)象連接,因?yàn)镾QLiteDatabase內(nèi)部對(duì)數(shù)據(jù)庫(kù)的操作是有同步處理的。

ContentProvider除了支持對(duì)數(shù)據(jù)源的增刪改查之外,還支持自定義調(diào)用,通過(guò)ContentResever和ContentProvider的Call方法來(lái)完成。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,412評(píng)論 6 532
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,514評(píng)論 3 416
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人,你說(shuō)我怎么就攤上這事。” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 176,373評(píng)論 0 374
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我,道長(zhǎng),這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 62,975評(píng)論 1 312
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 71,743評(píng)論 6 410
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 55,199評(píng)論 1 324
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,262評(píng)論 3 441
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 42,414評(píng)論 0 288
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 48,951評(píng)論 1 336
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 40,780評(píng)論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 42,983評(píng)論 1 369
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,527評(píng)論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,218評(píng)論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 34,649評(píng)論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 35,889評(píng)論 1 286
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 51,673評(píng)論 3 391
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 47,967評(píng)論 2 374

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