日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > Android >内容正文

Android

Android开发者指南(4) —— Application Fundamentals(二)

發布時間:2023/12/20 Android 41 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Android开发者指南(4) —— Application Fundamentals(二) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

線程安全方法(Thread-safe methods)

?????????在一些情況下,你所實現的方法有可能會被多于一個的線程所調用,所以它們必須被寫成線程安全的。

?????????對于我們上一節所討論的RPC機制中的可以被遠程調用的方法來說,這是必須首先考慮的。如果針對一個IBinder對象中實現的方法的調用源自這個?IBinder對象所在的進程時,這個方法將會在調用者的線程中執行。然而,如果這個調用源自其它的進程,則這個方法將會在一個線程池中選出的線程中運?行,這個線程池由Android加以管理,并與IBinder存在于同一進程內;這個方法不會在進程的主線程內執行。反過來說,一個服務的?onBind()?方法應為服務進程的主線程所調用,而實現了由?onBind()?返回的對象(比如說,一個實現了RPC方法的Stub的子類)的方法將為池中的線程所調用。因為服務可以擁有多于一個的客戶端,而同一時間,也會有多個池中的線程調用同一個IBinder方法。因此IBinder方法必須實現為線程安全的。

?????????類似的,一個內容提供者能接受源自其它進程的請求數據。盡管ContentResolverContentProvider類隱藏了交互溝通過程的管理細節,ContentProvider會由query()?insert()?delete()?update()getType()方法來相應這些請求,而這些方法也都是由那個內容提供者的進程中所包涵的線程池提供的,而不是進程的主線程本身。所以這些有可能在同一時間被很多線程調用的方法也必須被實現為線程安全的。

?

組件生命周期(Component Lifecycles)

應用程序組件有其生命周期──Android初始化它們以相應intent直到這個實例被摧毀。在此之間,它們有時是激活的有時則相反?;蛘?#xff0c;如果它是?一個activity,則是可為用戶所見或者不能。這一節討論了activity、服務以及廣播接收器的生命周期,包括它們在生命周期中的狀態、在狀態之?轉變時通知你的方法、以及當這些進程被關閉或實例被摧毀時,這些狀態產生的效果。

?

  Activity生命周期(Activity lifecycle)

?????????一個activity主要有三個狀態:

?*?當在屏幕前臺時(位于當前任務堆棧的頂部),它是活躍運行的狀態。它就是相應用戶操作的activity

?*?當它失去焦點但仍然對用戶可見時,它處于暫停狀態。即是:在它之上有另外一個activity。這個activity也許是透明的,或者未能完全遮蔽全屏,所以被暫停的activity仍對用戶可見。暫停的activity仍然是存活狀態(它保留著所有的狀態和成員信息并連接至窗口管理器),但當系統處于極低內存的情況下,仍然可以殺死這個activity

?*?如果它完全被另一個activity覆蓋是,它處于停止狀態。它仍然保留所有的狀態和成員信息。然而它不在為用戶可見,所以它的窗口將被隱藏,如果其它地方需要內存,則系統經常會殺死這個activity。

如果一個activity處于暫?;蛲V範顟B,系統可以通過要求它結束(調用它的?finish()?方法)或直接殺死它的進程來將它驅出內存。當它再次為用戶可見的時候,它只能完全重新啟動并恢復至以前的狀態。

當一個activity從這個狀態轉變到另一個狀態時,它被以下列protected方法所通知:

??????void onCreate(Bundle savedInstanceState)

void onStart()

void onRestart()

void onResume()

void onPause()

void onStop()

void onDestroy()

?????????你可以重載所有這些方法以在狀態改變時進行合適的工作。所有的activity都必須實現?onCreate()?用以當對象第一次實例化時進行初始化設置。很多activity會實現?onPause()以提交數據變化或準備停止與用戶的交互。

?

  調用父類(Calling into the superclass)

?????????所有activity生命周期方法的實現都必須先調用其父類的版本。比如說:

?????????

?????????總得來說,這七個方法定義了一個activity完整的生命周期。實現這些方法可以幫助你監察三個嵌套的生命周期循環:

?*?一個activity?完整的生命周期?自第一次調用?onCreate()開始,直至調用onDestroy()為止。activityonCreate()中設置所有全局狀態以完成初始化,而在onDestroy()中釋放所有系統資源。比如說,如果activity有一個線程在后臺運行以從網絡上下載數據,它會以?onCreate()創建那個線程,而以?onDestroy()銷毀那個線程。

?*?一個activity?可視生命周期?onStart()?調用開始直到相應的?onStop()調用。在此期間,用戶可以在屏幕上看到此activity,盡管它也許并不是位于前臺或者正在與用戶做交互。在這兩個方法中,你可以管控用來向用戶顯示這個activity的資源。比如說,你可以在onStart()?中注冊一個BroadcastReceiver?來監控會影響到你UI的改變,而在onStop()?中來取消注冊,這時用戶是無法看到你的程序顯示的內容的。onStart()??onStop()?方法可以隨著應用程序是否為用戶可見而被多次調用。

?*?一個activity?前臺生命周期??onResume()?調用起,至相應的?onPause()調用為止。在此期間,activity位于前臺最上面并與用戶進行交互。activity會經常在暫停和恢復之間進行狀態轉換──比如說當設備轉入休眠狀態或有新的activity啟動時,將調用onPause()?方法。當activity獲得結果或者接收到新的intent的時候會調用onResume()?方法。因此,在這兩個方法中的代碼應當是輕量級的。

下圖展示了上述循環過程以及activity在這個過程之中歷經的狀態改變。著色的橢圓是activity可以經歷的主要狀態。矩形框代表了當activity在狀態間發生改變的時候,你進行操作所要實現的回調方法。

?

?

下表詳細描述了這些方法,并在activity的整個生命周期中定位了它們。

方法

描述

是否可被殺死(Killable?)

下一個

onCreate()

activity第一次被創建的時候調用。這里是你做所有初始化設置的地方──創建視圖、綁定數據至列表等。如果曾經有狀態記錄(參閱后述Saving Activity State。),則調用此方法時會傳入一個包含著此activity以前狀態的包對象做為參數。

接下來始終遵循調用onStart()。

onStart()

onRestart()

activity停止后,在再次啟動之前被調用。

接下來始終遵循調用onStart()

onStart()

onStart()

activity正要變得為用戶所見時被調用。

activity轉向前臺時接下來調用onResume(),在activity變為隱藏時接下來調用onStop()

onResume()

onStop()

onResume()

activity開始與用戶進行交互之前被調用。此時activity位于堆棧頂部,并接受用戶輸入。

接下來始終遵循調用onPause()。

onPause()

onPause()

當系統將要啟動另一個activity時調用。此方法主要用來將未保存的變化進行持久化,停止類似動畫這樣耗費CPU的動作等。這一切動作應該在短時間內完成,因為下一個activity必須等到此方法返回后才會繼續。

activity重新回到前臺時接下來調用onResume()。當activity變為用戶不可見時接下來調用onStop()。

onResume()

onStop()

onStop()

activity不再為用戶可見時調用此方法。這可能發生在它被銷毀或者另一個activity(可能是現存的或者是新的)回到運行狀態并覆蓋了它。

如果activity再次回到前臺跟用戶交互則接下來調用onRestart(),如果關閉activity則接下來調用onDestroy()。

onRestart()

or

onDestroy()

onDestroy()

activity銷毀前調用。這是activity接收的最后一個調用。這可能發生在activity結束(調用了它的finish()?方法)或者因為系統需要空間所以臨時的銷毀了此acitivity的實例時。你可以用isFinishing()?方法來區分這兩種情況。

?????????請注意上表中可被殺死一列。它標示了在方法返回后,還沒執行activity的其余代碼的任意時間里,系統是否可以殺死包含此activity的進程。三個方法(onPause()、?onStop()和onDestroy())被標記為。onPause()是三個中的第一個,它也是唯一一個在進程被殺死之前必然會調用的方法──onStop()??onDestroy()?有可能不被執行。因此你應該用?onPause()?來將所有持久性數據(比如用戶的編輯結果)寫入存儲之中。

?????????可被殺死一列中標記為的方法在它們被調用時將保護activity所在的進程不會被殺死。所以只有在onPause()方法返回后到onResume()?方法被調用時,一個activity才處于可被殺死的狀態。在onPause()再次被調用并返回之前,它不會被系統殺死。

????如后面一節進程和生命周期所述,即使是在這里技術上沒有被定義為可殺死activity仍然有可能被系統殺死──但這僅會發生在實在沒有其它方法的極端情況之下。

?

  保存activity狀態(Saving activity state)

?????????當系統而不是用戶自己出于回收內存的考慮,關閉了一個activity之后。用戶會期望當他再次回到那個activity的時候,它仍保持著上次離開時的樣子。

?????????為了獲取activity被殺死前的狀態,你應該為activity實現onSaveInstanceState()?方法。Androidactivity有可能被銷毀之前(即onPause()?調用之前)會調用此方法。它會將一個以名稱-值對方式記錄了activity動態狀態的Bundle?對象傳遞給該方法。當activity再次啟動時,這個Bundle會傳遞給onCreate()方法和隨著onStart()方法調用的onRestoreInstanceState(),所以它們兩個都可以恢復捕獲的狀態。

?????????onPause()或先前討論的其它方法不同,onSaveInstanceState()??onRestoreInstanceState()?并不是生命周期方法。它們并不是總會被調用。比如說,Android會在activity易于被系統銷毀之前調用?onSaveInstanceState(),但用戶動作(比如按下了BACK鍵)造成的銷毀則不調用。在這種情況下,用戶沒打算再次回到這個activity,所以沒有保存狀態的必要。

?????????因為onSaveInstanceState()不是總被調用,所以你應該只用它來為activity保存一些臨時的狀態,而不能用來保存持久性數據。而是應該用onPause()來達到這個目的。

?

  服務生命周期(Coordinating activities)

?????????服務以兩種方式使用:

?*?它可以啟動并運行,直至有人停止了它或它自己停止。在這種方式下,它以調用Context.startService()啟動,而以調用Context.stopService()結束。它可以調用Service.stopSelf()??Service.stopSelfResult()來自己停止。不論調用了多少次startService()方法,你只需要調用一次stopService()來停止服務。

?*?它可以通過自己定義并暴露出來的接口進行程序操作??蛻舳私⒁粋€到服務對象的連接,并通過那個連接來調用服務。連接以調用Context.bindService()方法建立,以調用?Context.unbindService()關閉。多個客戶端可以綁定至同一個服務。如果服務此時還沒有加載,bindService()會先加載它。

這兩種模式并不是完全分離的。你可以綁定至一個用?startService()啟動的服務。比如說,一個后臺音樂播放服務可以調用startService()并傳遞給它一個包含欲播放的音樂列表的Intent對象來啟動。不久,當用戶想要對播放器進行控制或者查看當前播放曲目的詳情時,會啟用一個activity,調用bindService()連接到服務來完成操作。在這種情況下,直到綁定連接關閉stopService()?才會真正停止一個服務。

activity一樣,服務也有一系列你可以實現以用于監控其狀態變化的生命周期方法。但相對于activity要少一些,只有三個,而且,它們是public屬性,并非protected

void onCreate()

void onStart(Intent intent)

void onDestroy()

?????????倚仗實現這些方法,你監控服務的兩個嵌套的生命周期循環:

?*?服務的完整生命周期始于調用onCreate()而終于onDestroy()方法返回。如同activity一樣,服務在onCreate()里面進行它自己的初始化,而在onDestroy()里面釋放所有資源。比如說,一個音樂回放服務可以在onCreate()中創建播放音樂的線程,?而在onDestroy()中停止這個線程。

?*?服務的活躍生命周期始于調用onStart()。這個方法用于處理傳遞給startService()Intent對象。音樂服務會打開Intent來探明將要播放哪首音樂,并開始播放。

服務停止時沒有相應的回調方法──不存在onStop()方法。

???????? onCreate()onDestroy()方法在所有服務中都會被調用,無論它們是由Context.startService()還是由Context.bindService()所啟動的。而onStart()僅會被startService()所啟用的服務調用。

?????????如果一個服務允許別的進程綁定,則它還會有以下額外的回調方法以供實現:

IBinder onBind(Intent intent)

boolean onUnbind(Intent intent)

void onRebind(Intent intent)

?????????傳遞給bindServiceIntent的對象也會傳遞給onBind()回調方法,而傳遞給unbindService()Intent對象同樣傳遞給onUnbind()。如果服務允許綁定,onBind()將返回一個供客戶端與服務進行交互的通訊渠道。如果有新的客戶端連接至服務,則onUnbind()方法可以要求調用onRebind()?。

?????????下圖描繪了服務的回調方法。盡管圖中對由startService?startService方法啟動的服務做了區分,但要記住,不論一個服務是怎么啟動的,它都可能允許客戶端的連接,所以任何服務都可以接受onBind()onUnbind()調用。

?

?

廣播接收器生命周期(Broadcast receiver lifecycle)

?????????廣播接收器只有一個回調方法:

???????? ?????????void onReceive(Context curContext, Intent broadcastMsg)

?????????當廣播消息抵達接收器時,Android調用它的onReceive()?方法并將包含消息的Intent對象傳遞給它。廣播接收器僅在它執行這個方法時處于活躍狀態。當onReceive()返回后,它即為失活狀態。

?????????擁有一個活躍狀態的廣播接收器的進程被保護起來而不會被殺死。但僅擁有失活狀態組件的進程則會在其它進程需要它所占有的內存的時候隨時被殺掉。

?????????這種方式引出了一個問題:如果響應一個廣播信息需要很長的一段時間,我們一般會將其納入一個衍生的線程中去完成,而不是在主線程內完成它,從而保證用戶交互過程的流暢。如果onReceive()衍生了一個線程并且返回,則包涵新線程在內的整個進程都被會判為失活狀態(除非進程內的其它應用程序組件仍處于活躍狀態),于是它就有可能被殺掉。這個問題的解決方法是令onReceive()啟動一個新服務,并用其完成任務,于是系統就會知道進程中仍然在處理著工作。

?????????下一節中,我們會討論更多進程易誤殺的問題。

?

進程與生命周期(Processes and lifecycles)

???????? Android系統會盡可能長的延續一個應用程序進程,但在內存過低的時候,仍然會不可避免需要移除舊的進程。為決定保留或移除一個進程,Android?將每個進程都放入一個重要性層次中,依據則是它其中運行著的組件及其狀態。重要性最低的進程首先被消滅,然后是較低的,依此類推。重要性共分五層,依?據重要性列表如下:

1.?????????前臺進程是用戶操作所必須的。當滿足如下任一條件時,進程被認為是處于前臺的:

*?它運行著正在與用戶交互的activityActivity對象的?onResume()?方法已被調用)。

*?一個正在與用戶交互的activity使用著它提供的一個服務。

*?它包含著一個正在執行生命周期回調方法(onCreate()、onStart()onDestroy())的Service對象。

*?它包含著一個正在執行?onReceive()?方法的BroadcastReceiver對象。

任一時間下,僅有少數進程會處于前臺,僅當內存實在無法供給它們維持同時運行時才會被殺死。一般來說,在這種情況下,設備已然處于使用虛擬內存的狀態,必須要殺死一些前臺進程以用戶界面保持響應。

2.?????????可視進程沒有前臺組件,但仍可被用戶在屏幕上所見。當滿足如下任一條件時,進程被認為是可視的:

*?它包含著一個不在前臺,但仍然為用戶可見的activity(它的onPause()方法被調用)。這種情況可能出現在以下情況:比如說,前臺activity是一個對話框,而之前的activity位于其下并可以看到。

*?它包含了一個綁定至一個可視的activity的服務。

可視進程依然被視為是很重要的,非到不殺死它們便無法維持前臺進程運行時,才會被殺死。

3.?????????服務進程是由?startService()?方法啟動的服務,它不會變成上述兩類。盡管服務進程不會直接為用戶所見,但它們一般都在做著用戶所關心的事情(比如在后臺播放mp3或者從網上下載東西)。所以系統會盡量維持它們的運行,除非系統內存不足以維持前臺進程和可視進程的運行需要。

4.?????????背景進程包含目前不為用戶所見的activityActivity對象的?onStop()?方法已被調用)。這些進程與用戶體驗沒有直接的聯系,可以在任意時間被殺死以回收內存供前臺進程、可視進程以及服務進程使用。一般來說,會有很多背景進程?運行,所以它們一般存放于一個LRU(最后使用)列表中以確保最后被用戶使用的activity最后被殺死。如果一個activity正確的實現了生命周?期方法,并捕獲了正確的狀態,則殺死它的進程對用戶體驗不會有任何不良影響。

5.?????????空進程不包含任何活動應用程序組件。這種進程存在的唯一原因是做為緩存以改善組件再次于其中運行時的啟動時間。系統經常會殺死這種進程以保持進程緩存和系統內核緩存之間的平衡。

Android會依據進程中當前活躍組件的重要程度來盡可能高的估量一個進程的級別。比如說,如果一個進程中同時有一個服務和一個可視的activity,則進程會被判定為可視進程,而不是服務進程。

此外,一個進程的級別可能會由于其它進程依賴于它而升高。一個為其它進程提供服務的進程級別永遠高于使用它服務的進程。比如說,如果A進程中的內容提供者?為進程B中的客戶端提供服務,或進程A中的服務為進程B中的組件所綁定,則A進程最低也會被視為與進程B擁有同樣的重要性。

?????為運行著一個服務的進程重要級別總高于一個背景activity。所以一個activity以啟動一個服務的方式啟動一個長時間運行過程比簡單的衍生一個?線程來進行處理要好。尤其是當處理過程比activity本身存在時間要長的情況之下。我們以背景音樂播放和上傳一個相機拍攝的圖片至網站上為例。使用服?務則不論activity發生何事,都至少可以保證操作擁有服務進程的權限。如上一節廣播接收器生命周期所提到的,這也正是廣播接收器使用服務,而不是使用線程來處理耗時任務的原因。

?


本文轉自over140 51CTO博客,原文鏈接:http://blog.51cto.com/over140/582308,如需轉載請自行聯系原作者

總結

以上是生活随笔為你收集整理的Android开发者指南(4) —— Application Fundamentals(二)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。