軟體開發 Android Life Cycle (1)

基本介紹

教學目標

開發 Android 會面臨到網路傳輸的問題,當存取網路資源時,會使得 Activity 發生短暫停頓,畫面變黑的狀態,甚至強制終止應用程式 App,這些皆會給使用者操作體驗的印象非常的不良,因此要如何解決這種問題呢?

重點概念

為了解決上述問題,最好的方式就是了解 Android 生命週期,基本上可以分成 Activity 生命週期和 Process 生命週期。

Activity

首先在系統中的每個 Activity 會透過 Activity 堆疊進行管理,簡單來說,當有新的 Activity 被啟動後會被加入至 Activity 堆疊最上層,此時該 Activity 的狀態為 Running。

生命週期

有四種主要的狀態:

  • Running
    Activity 在前景畫面執行時的狀態為主動或執行中。
  • Paused
    Activity 已經失去了焦點,但仍可見 (以全新非全尺寸或透明的方式呈現),此時會將焦點集中在最上層的 Activity,此時的狀態就是已暫停。此外暫停的 Activity 繼續存活著,會維護所有的狀態和成員資訊,保持與管理器的連線,會當系統在記憶體極端低的情況下被刪除。
  • Stopped
    如果 Activity 完全被另一個 Activity 覆蓋,此時狀態已停止,雖然保留所有狀態和成員信息,但是不再是使用者可見的 Activity,所以當系統在記憶體即需要的情況下會被刪除。
  • Restarted
    如果 Activity 已經被暫停或停止,該系統就可以從記憶體中刪除該 Activity 的程序,或者要求完成該 Activity 所執行的程序。除此之外 當它需要再次顯示給用戶,就必須完全重新啟動和恢復到以前的狀態,此時的狀態就是已重新啟動。

流程圖

Activity 狀態流程圖

開發重點

有三種主要的關鍵:

  • Entire
    Activity 完整生命週期會發生在一開始呼叫 onCreate() 至最後單獨呼叫 onDestroy()。舉例來說,若有執行緒在背景執行從網路下載資料,一開始會在 onCreate() 建立執行緒以及最後會在 onDestroy() 停止執行緒。
  • Visible
    Activity 可見生命週期會發生在一開始呼叫 onStart() 直到調用相對應的 onStop(),在此期間,使用者會看到螢幕上的 Activity,雖然它可能不會在前景與使用者進行互動。除此之外,在這兩個方法之間您可以維護所需要顯示 Activity 相關資源給使用者。舉例來說,您可以在 onStart() 註冊 BroadcastReceiver 在於監控和改變您的使用者介面所造成的影響以及當使用者不再需要您的顯示時可在 onStop() 取消註冊。
  • Foreground
    Activity 前景的生命週期會發生在 onResume() ,直到調用相對應的 onPause(),在此期間 Activity 會在其它 Activity 之前景和使用者進行互動,也因此 Activity 的狀態經常會是 Resumed 或者 Paused。舉例來說,當裝置要進行休眠時,當 Activity 結果被交付時,當新 Intent 被交付時才會發生,因此,在這兩個方法在程式碼中應該算是相當輕量級的應用。

Process

當記憶體執行過低時,系統就會自動刪除比較不重要的 Process ,然而當 Activity 的 Running 狀態時, Process 會有狀態。

生命週期

有四種主要的狀態:
一般來說,基於 Activity 的 Running 狀態時,Process 會有四種狀態:

  • Foreground
    前景的 Process 被認定最重要,簡單來說就是在畫面最上方且正與使用者進行互動的 Activity,當裝置需要使用更多的記憶體,這時當 Process 刪除只能當成最後的手段。此外一般來說裝置會有記憶體分頁狀態,為了保持使用者介面的回應這是必須的。
  • Visible
    可見的 Process 被認定是極重要的,簡單來說就是不是在前景,而是在前景的對話框中,除非是需要保持前景 Activity 的執行,否則將不會被刪除。
  • Background
    背景的 Process 基本上不是很重要,簡單來說就是非可見的 Activity ,或者已經暫停的 Activity,所以系統可以為了其它前景的 Process ,或者可見的 Process 需要記憶體時,安全刪除這類的 Process。當使用者導航回 Activity 再一次恢復為可見的狀態,onCreate() 和 onSaveInstanceState() 等方法此時將會被呼叫,也就是說它會重新設定回上次離開時的狀態。
  • Empty
    空白的 Process 是任何活動或應用程式的元件,也就是 Service,或者 BroadcastReceiver 等相關類別,最特別的是當系統的記憶體變少時這些 Process 會被非常快的刪除,出於這個原因,任何背景操作必須在 Activity 中的 Service ,或者 BroadcastReceiver 中執行,確保系統知道它需要保持您的 Process 正常執行。

舉例來說,可能有相機的應用程式允許你上傳相片至網站,此時上傳可以會花費很長的時間,所以相機的應用程式會允許使用者先去處理其它的應用程式,並將相機的應用程式在背後持續執行,而當相片上傳完成後會開啟服務。也就是說系統會依照不同的階段 ( Paused 、 Stopped 和 Finished ) 給予 Process 適當的優先權。

Thread

在了解 Process 的生命週期之後,最後就要了解的就是 Thread , Thread 是平行的執行單元,稱之為執行緒,它有本身呼叫堆疊的方法被調用。每個 Thread 有參數和區域變數,簡單來說每個虛擬機器的實體都有至少一個主要的執行緒在開始時執行,此外應用程序可能為特定目的而決定啟動額外的執行緒。

而要實作的就是在 Activity 執行時,啟動 Process,再透過 Thread 執行 Socket 存取網路資源,整體看起來並沒有什麼問題,但是當網路傳輸的資料量過大時,就會發生問題,也就是 Application Not Responding ,簡稱 ANR ,簡單來說,當應用程式無法回應使用者的輸入,例如 I/O 操作,通常是網路連線 App 的程式區塊,然後主要的 App 執行緒會將不能夠處理的使用者輸入事件,在經過一段時間:

  • 在 5 秒內沒有回應輸入事件,如按鍵,觸碰螢幕。
  • 在 10 秒內 尚未執行 BroadcastReceiver 完成。

系統將會終結,應用程式被凍結,並且系統會顯示 ANR 的資訊給使用者關閉該應用程式 App。

解決方式

再了解 Activity 、 Process 和 Thread 的基本概念之後,回頭面對上述問題其實可以透過 StrictMode 確保主要的執行緒正常執行,但是若想避免這問題發生,基本上可透過非同步的網路方式進行資訊的傳輸,簡單來說就是透過 AsyncTask 類別進行非同步的網路傳輸。

相關資源