/* syntax highlight */ /* end of syntax highlight */

2010年11月25日 星期四

iphone app 開發 (十) – iPhone App 應用程式的生命週期

Bookmark and Share

image

上圖就是 iPhone OS 的程式設計架構 (iOS 3.0) 版,4.0版事實上有增加一些東西,之後會提到

應用程式的生命週期,從開始到結束所需進行的步驟

左方是 UIkit,右方是我們所撰寫的程式碼

 

透過我們撰寫的 code 來操控 UIkit 的物件與事件

icon 點進去之後,就會進入 Main() 主要入口點

然後會帶我們到 UIApplicationMain () 是我們的 App 主要進入點

接下來的 Event Loop 是一個無窮迴圈

我們可以設計一些傾廳的機制,等待使用者觸發事件或按下哪個按紐

但是如果使用者按下 home 或是有人打電話過來時,就會觸發下面的

System ask Application to quit foreground

然後是進到背景執行時的 Application moves to backgroud

 

這邊需要了解 App 的狀態,這裡引用 Austin’s study note 裡面整理的

 

了解應用程式的狀態和狀態轉變

iPhone OS 4.0 針對多工有增加一些 OS 3.0 沒有的 Application states,這節簡單敘述一下

Not running
程式完全沒有執行乖乖躺在 Flash 的狀態。

 

Inactive
應用程式在前景(foreground)執行但是停止接收 event,通常是因為系統有其他任務必須立刻告知使用者, 如收到簡訊會將目前執行的應用程式強制進入 Inactive 並在螢幕上告知使用者等待使 用者回應 (按下OK)。

 

Active
應用程式在前景(foreground)執行,且可以正確接收所有events。

 

Background
應用程式在背景(background)執行,通常在應用程式被要求進入 suspend state 前會短暫的進入 background state 好讓應用程式可以有時間處理些收尾的動作,如記錄目前狀態等等。這是iPhone OS 4.0 新增的狀態,詳細說明可以參考本文 Executing Code in the Background 章節。

 

Suspended
應用程式在背景(background)但不繼續執行,應用程式此時依然留在主記憶體中,所以重新喚起 需要的資源較少,時間也較短。 如果記憶體不夠系統會在毫無任何通知下自行移除處於 suspended state 的應用程式,基本上由最久沒有回到Active state的應用程式開始移除。

 

 

以下再根據流程依序做介紹

 

User taps application icon

image

 

 

main()

main 是程式的進入點,在 Xcode 當中的話,在 Other Sources / main.m 這支程式裡面有下面的 code,為 Xcode 自動產生的程式碼

  1. int main(int argc, char *argv[]) {  
  2.    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
  3.    int retVal = UIApplicationMain(argc, argv, nil, nil);
  4.    [pool release];  
  5.    return retVal;
  6. }

 

main()函數為程式入口點,功能使用時大部分被UIApplicationMain()函數所取代,一般來說main()函數主要會執行三件事

(1) 建立autorelease pool  (第2行) - 建立池子,收集資源,將來如果物件不使用,將會自動垃圾收集

(2) 呼叫UIApplicationMain 之方法 (第3行) - 建立 Application UI 之物件 (後面4個參數通常不需做更改)

(3) 釋放autorelease pool  (第4行) - 釋放不使用的物件,將資源還給手機

 

 

UIApplicationMain ()

UIApplicationMain() 主要是 App 進入點,設定應用程式派遣(Application Delegate),負責派遣物件完成指定工作,流程可以看下圖:

image

Launch App 之後,會先讀取 main nib 並創造一個 Application delegate ,開始派潛任務,等到 App 初始化之後,就開始看使用者執行了什麼任務,再根據這些任務去讀去相對應的 application delegate 。

 

 

Event Loop

當使用者執行以下幾個行為的時候,有可能會觸發 App 產生 Event ,如下圖

image

  • 觸發 - touch event (Multitouch events)
  • 移動 - motion event ( Accelerometer events)
  • 外部訊號 - remote-control event ( Remote-control event)

 

至於觸發之後會產生的事件流程,則如下圖

image

手指先觸碰 App 的 view 裡面的 icon 之後,動作會傳給 OS (Cocoa framework),接下來會將使用者的動作傳給 Event queue (因為使用者有可能同時執行多項動作),Event Queue 是一個緩衝區的概念,接下來 應用程式派遣(Application Delegate) 將會抓出對應的 Event ,利用 Core Objects 處理之後,回傳到 OS ,再回傳 UI 讓使用者看到。

 

再來我們看下一張圖

image

系統會不斷將他所收到的 event 丟進 event queue 當中,而 UIApplication 這個物件則會不斷向 event queue 去 fetch 這些 event ,並包裝成 UIevent 然後丟給 UIResponder,不一定每個 UIResponder都對每個 UIevent 有興趣,所以如果第一個 UIResponder 沒有處理掉,就會丟給第二個 UIResponder ,以此類推。

 

 

System “ask” Application to quit foreground

至於被 Interrupt 之後會觸發的 Application delegate ,我們利用下圖說明

image

當有人打電話過來,簡訊,日曆訊息之後,會啟動 applicationWillResignActive 這個方法 ,我們可以寫程式來加入對應的事件。如果使用者選擇忽略,則會呼叫 applicationWillBecomeActive 這個方法來恢復程式的狀態,但是如果使用者選擇 no 的話,Application 將會進入 backgroup,並呼叫 applicationDidEnterBackgroup 方法。

 

 

Application moves to backgroud

這個部份其實跟上部份的圖是接在一起的,也就是當使用者選擇接聽電話或是觀看簡訊的話,Application 將會跳到 backgroup 執行。

 

 

Application back to foreground

如果使用者聽完電話想要回到 foregroud,將會觸發以下流程

image

一樣,Application Delegate 會派繾以下兩個方法, applicationWillEnterForeground 以及 applicationDidBecomeActive,我們都可以在程式裡面去撰寫相對應的 Event。

 

以上就是 iPhone 應用程式的生命週期,事實上我們在打開 Xcode 之後,這些程式碼都會自動產生,對於初學者來說應該會覺得很莫名其妙這些 code 到底哪來的,但是對於熟練一點的人來說,這些程式碼都是必須要寫的,如果能夠在一開始就產生其實很方便。

 

 

參考資料

iPhone Application Programming Guild (note1)

2 意見:

阿勳 提到...

很淺顯易懂 感謝分享

彭其捷 提到...

謝謝樓上的回覆 :p
我也正在努力學習中

張貼留言

Related Posts Plugin for WordPress, Blogger...