2011年11月16日 星期三

Back&Home鍵在Android對Thread的影響

Android 2.2
以下是個人心得,對錯不負任何責任 :)
-------

原理:





App開啟時:
  1. onCreate()
  2. onStart()
  3. onResume()

 

若按下Back鍵:
  1. onPause()
  2. onStop()
  3. onDestroy()
  4. 再次啟動app
  5. onCreate()
  6. onStart()
  7. onResume()


若按下Home鍵:
  1. onPause()
  2. onStop()
  3. "onDestory()無法預測何時會被啟動(由os依資源決定)"
  4. 再次啟動app
  5. onResume()

 

因此我們可以看出Back鍵及Home鍵二者主要的差異在於是否主動觸發 onDestory(),並影響了重啟app時,是否會再次執行 onCreate()。當 onDestory() 被觸發後,則 Thread 不會有問題,因整個app流程會從頭再執行一次,此時 Thread '通常' 會在 onCreate() 被重新宣告並在稍後呼叫 Thread.start()。當onDestory() 沒有被觸發,則 Thread.start() 有很大的可能會被重呼,因 onResume() 通常會被用來重新呼叫該app要處理的事,包括Thread要處理的事。此時就會產生以下的錯誤:

錯誤: "Thread already started"

解決方法:

A. 利用Object的lock方式來控制 Thread.wait() 及 Thread.notifyAll()

B. 中止 Thread (ex: 利用thread = null及Thread.interrupt()),每次 onResume() 都重新產生 Thread 然後Thread.start()

C. 不繼承 Thread,只實作 runnable 方法

個人認為:

最無腦解法: B > C > A

最能廣泛運用: A > B > C

若只是處理非持續的邏輯運作: C > B > A

======================================================

當 Thread 處理的邏輯過於複雜時或是 Thread 的生命周期和app是一樣時,則方案 C 就不太適合。在 A/B 中選擇的話,個人是偏好 方案B 的作法,畢竟 方案A 在app不處於使用者可見下還是會佔去資源。方案B 搭配 Bundle 來恢復app中一些使用者狀態就能處理大部份的狀況了。但 方案B 似乎相當不適合在多重 Thread 的情況下使用,否則每次onResume()都要重新處理一堆工作,但這部份還是要看使用多Thread的目地是什麼來決定。

我不喜歡方案A,因此會避開一定要用方案A 的情境,所以對方案A就沒什麼可分享的了 :)

======================================================

情境範例:

- 使用一Thread來(非連續性)更新Activity中某些元件的值: 使用方案C 在onResume()及onPause()進行更新的判斷。重點是不要在create Activity時進行任何更新值的動作,否則會因onResume()又被呼叫,於是造成二次更新的資源浪費。

- 使用一Thread持續更新SurfaceView畫面: 使用方案B 在SurfaceView.surfaceCreated() 及 SurfaceView.surfaceDestroyed()。避免在 Activity.onResume() 及 onPause() 中控制 Thread,因為Thread 雖然與 Activity 共生死,可是與 Activity 其實沒有任何邏輯關聯性。

沒有留言:

張貼留言