2009年7月6日 星期一

Android Process Lifecycle

Android系統記憶體不足時, 就需要把舊的或不需要用的應用程式移除. 如同之前的Activity生命週期所介紹, 這個移除的決定是由應用程式所處的狀態來判斷. 一般來說,當需要移除應用程式時, 系統將會做排序, 然後從最不重要的開始移除, 以下是移除時的考量順序:



1. 最早被移除的是 Empty Process(空行程):
Empty process 是指那些沒有跟Activity綁定, 也沒有跟任何的應用程式元件(比如Service或IntentReceiver)綁定在一起的process, 這些空行程一定是最早被系統考慮移除的.


2. 第2順位考慮被移除的是 Background Activity.
Background Activity指這個activity是無法被使用者看到的的情況, 表示Activity已處於stop的狀態, 系統移除這些 Activity 是安全的. 通常有多個 Background Activity同時運行, 這些Activity被存放在一個 LRU (least recent used) list中, 系統可以根據 LRU list 判斷哪些 Activity可以被移除, 哪一個應該是最先被移除的.

3. 第3順位被移除的是 Service Process.
在 Android 應用程式裡, 有一種沒有 UI 的類別(android.app.Service), 稱之為 Service. Service Process 通常是由startService()方式啟動. 簡單來說,Service 屬於 background(背景)程序, 透過背景程序, 我們可以製作一些不需要 UI 的功能, 例如: 在背景撥放音樂, 上傳或下載文件等. 系統通常會保護它, 除非真的沒有記憶體可用.

4. 接著輪到 Visible Activity / Visible Process:
Visible Process是一個可被Visible的, 但是沒有顯示在最上端 (onPause被使用時). 舉例來說, 當一個新的對話框Activity出現時, 原來的Activity仍然visible, 仍然被系統認為是重要的, 通常不會被移除. 但若不得不移除時, 由於屬於 Paused狀態, 相對來說, 它已經處於一個比較安全的位置.

5. 最後被移除的是 Foreground Activity:
Foreground是一個在螢幕最上端與使用者做互動的Activity, 它的優先權最高. 原則上會是最後一個被移除的程式, 除非這個Activity所需要的記憶體大小已經超出系統所能給的. 系統之所以會移除這些程序, 是為了不讓使用者介面停止回應.

由於Android應用程式的lifecycle並不是由程式本身直接控制的, 而是由系統平台進行管理. 所以對於開發者而言, 許要了解不同元件 Activity, Serivce 和 IntentReceiveer的Lifecycle. 要切記: 如果元件使用不當, 雖然正在進行重要的Process, 仍有可能被系統主動移除.

Android Activity生命週期簡介

前面有提到何謂Activity: 最簡單的就是把Activity看成一個User Interface Program. 它會提供使用者一個互動式的介面功能. 當然一個activity通常不只一個UI, 所有的Activity在系統裏由Activity stack 所管理, 當一個新的Activity被執行後,它將會被放置到stack的最頂端,並且變成"running activity", 而之前的Activity原則上還是存在stack中,但不會是在foreground(前景)的情況.

一個Activity基本上有四個狀態 Active, Paused, Stopped, Dead:
Activity 處在Paused狀態時, 使用者無法與原來的 Activity 互動.


Dead/Inactive (已回收或未啟動)
Dead狀態是 Activity 尚未被啟動, 已經被手動終止, 或已經被系統回收的狀態.
要手動終止 Activity, 可以在程式中呼叫 finish 函式.
如果是被系統回收, 可能是因為記憶體不足, 系統根據記憶體不足時的回收規則, 將處於Stopped狀態的 Activity 所佔用的記憶體回收.


下面的流程圖說明一個Activity運行的情況, 長方形代表callback methods(回呼函式), 可以做出想要處理的事情, 有顏色的部份就是實際Activity會處於的狀態.






上圖有三個主要 lifetime :

1. Entire lifetime: 一個Activity的Entire lifetime是由onCreate()開始, 一直到onDestroy()結束.
一個Activity可以把所有的資源設定寫在onCreate中, 一直到onDestroy()時再釋放出來.

2. Visible lifetime: 一個Activity的Visible lifetime是指在onStart()到onStop()之間.
在這段時間內,使用者可以在螢幕上看見Activity, 要注意這個"Visible"是個形容, Activity不見得一定在foreground(前景)跟使用者直接互動.

3. Foreground lifetime: 一個Foreground lifetime 指 onResume() 到 onPause() 之間. 這個時期的Activity是在其他的Activity的前面, 且可以直接跟使用者進行互動. 所以這段時期指的就是圖中的Activity is running.


簡單的總結幾個動作:
onCreate()用來做程式的初使化動作;
onDestory()通常都拿來把onCreate()時的資料做釋放的動作;
onPause()時把需要保存的資料保存;
onResume()把保存的資料拿回來使用.


onCreate -> onStart -> onResume
啟動一個 Activity 的基本流程是: 分配資源給這個 Activity(onCreate), 然後將 Activity 內容顯示到螢幕上(onStart), 在一切就緒後, 取得螢幕的控制權(onResume), 使用者可以開始使用這個程式。

onPause(1) -> onCreate(2) -> onStart(2) - onResume(2) -> onStop(1)
先凍結原本的 Activity, 再交出直接存取螢幕能力(onPause )的過程. 直到 Activity 2 完成一般啟動流程後, Activity 1 才會被停止.

onPause(2) -> onRestart(1) -> onStart(1) -> onResume(1) -> onStop(2) -> onDestroy(2)
按 Back鍵可以回到原本的 Activity。

onPause -> onStop -> onDestroy
如果程式中有直接呼叫 finish 函式來關閉 Activity的話, 系統會暫停(Pause), 停止(Stop)然後銷毀(Destroy)。

onCreate -> onStart -> onResume
被回收掉的 Activity 一旦又重新被呼叫時,會像一般啟動一樣再次呼叫 Activity 的 onCreate 函式.



幾個 Android 的名詞觀念

在真正進入 Android 程式設計前,必須先了解以下幾個名詞觀念。

1. Android Package (.apk):
包含應用程式本身,以及相關的資源檔案。將 apk 套件下載到 Android 手機後,即可安裝至手機上。Android Development Kit 可自動將 apk 套件下載至模擬器或實體手機。
記得前面我們在 Eclipse 中若要檢視HelloWorld程式時, 是利用 Package Explorer 來查看整個程式的結構的.

2. Task
Task 為"工作"的意思, 可以看成 Application (應用程式)本身. 也就是手機上的應用程式的圖示,使用者可點擊圖示啟動 task。從開發者的角度來看

3. Process
Process 的定義上,指的是"執行中的程式",在 Android 的Application 環境中,代表低階的執行程式,屬於 Kernel 部份。一個 package 的所有程式,都是在一個 process 中執行。
在一般情況下, Android 應用程式都有一個自已的 Process. 在 Android 系統裡, Process 的生命週期(life cycle) 並不是直接由 Android 應用程式本身來決定, 而是由系統來決定.
Android 的 process 有五種類型:foreground process、visible process、service process、background process 與 empty process。

4. Activity
Activity是Android開發中非常重要的一個基礎類。就字面上來說, Activity 就是"活動"的意思. 可以簡單的解釋為, Activity 是一個與使用者互動的物件(object)。
舉例來說:一個EMail程式,就可能包含三個activity: 有列出郵件的 Activity 1, 顯示郵件內容的activity 2, 及 撰寫郵件 activity3.
Activity 大概可以分成四種生命狀態:
一個Activity在螢幕的最上層時(堆疊的最頂端),它就是屬於activerunning的狀態
如果一個Activity失去focus(焦點)但還看得到它的畫面(例如:一個Activity畫面是被蓋掉部份畫面或一個半透明的情況), 這個Activity則處在 paused 的狀態。這個失去焦點的Activity它還是完全活著的, 並沒有消失。(活著的意思是指,Activity本身所有的狀態及資料都還是存在,與管理程式保持連繫). 但這種paused的activity, 會在某些情況下消失, 例如當系統的記憶體不夠用時, 系統會自動判斷, 把不重要的activity移除.

如果一個Activity被其它的Activity完全的遮住時, 這個被遮的Activity處於stop的狀態, 但它仍然保有全部的狀態及資料. 由於它已不被使用者看見,所以它的畫面是被隱藏起來的, 當系統記憶體不足時,這種stop狀態的activity是最先被系統考慮移除以釋放記憶體.

當一個Activity處於pause或stop的狀態時, 系統可以要求Activity結束(finish)或移除(kill)它. 當它需要再度呈現在使用者面前時, 它必需要能完整的重新啟動(restart)及回復(resume)先前的狀態。

5. View
簡單來說,android.app.View 類別就是手機的 User Interface. View 負責繪製UI與 event (處理事件). Android 利用 View 建立所謂的 Widgets(元件), 利用 Widget 就可以製作互動式的使用者介面(interactive GUI).

2009年7月5日 星期日

認識 Android 程式架構 (2)

在進入程式內容分析之前, 先了解一下 Android 軟體架構
在Android架構,總共是由5個部份來組成。分別是:

(1)Applications (應用程式)
(2)Application Framework (應用程式架構)
(3)Libraries (函式庫)
(4)Android Runtime (Android執行環境)
(5)Linux Kernel (Linux核心)








上面的圖很清楚的表達了Android 的架構.
從圖上看來, Android像是一種 software stack 的 架構, 雖然可能常跟 WinCE、Linux 之類的 OS 來做比較, 但是感覺上 Android 不像是是個 OS. (但是也有人主張他是一個 OS).

我們從底層開始向上說明:

Android 最底層還是拿 Linux 做為 Kernel. (Linux Kernal 是什麼, 先不討論)

然後中間有一些 Libraries (使用的是C/C++的函式庫). 屬系統元件, 開發者可以透過 Application Framwork 來使用這些功能.


在同一層有個 Android Runtime, 其中有 Core Libraries 是專門為手機的應用而發展的, 裡頭已經包含了絕大多數Java所需要呼用的函式.
而 Dalvik Virtual Machine (Dalvik虛擬機器, 簡稱 DVM) , 是一種暫存器型態(Register Based)的虛擬機器. 這樣的安排可以讓應用程式具有移植性. 要注意的是而且Android不是用一個 DVM來同時執行多個應用程式,而是每個應用程式都用一個自已的DVM來執行。



再上一層的的 Application Framwork 是讓開發者在寫應用程式時可以完整的使用標準的應用程式介面. 這樣的架構可以很容易的去重覆使用各個元件; 應用程式可以提供出它自己的特殊功能, 也可以較容易的去使用其它程式的特殊功能。這樣的機制有助於開發者去改寫自己新的軟體元件.
以大方向來看,加入新的 library 時需要擴充 application framework;Android framework 以 JNI 呼叫下一層的 library,但是 application 不直接呼叫 library,因此讓 Android framework 的設計更嚴謹。(這一部分較為進階, 以後慢慢會懂)


而最上層的 Applications 都是以以Java語言撰寫的應用程式,電子郵件程式、簡訊程式、日曆、地圖、瀏覽器、聯絡人... 等都屬於application (應用程式). 簡單的說就是讓使用者使用這些applications來操作及應用手機功能.

初學 Android 就是要在 在Android SDK(軟體開發套件)所用提供的開發環境下, 用Java 語言撰寫Application。

2009年7月3日 星期五

認識 Android 程式架構 (1)

利用 HelloWorld 程式來大略看一下Android 的程式架構.
我們在 Package Explorer 中將 HelloWorld 點開. 應該可以看到如下的資料結構:









結構中 src, gen, Android 1.1, assets, res, AndroidManifest.xml 為同一階層.

src : 放置主程式、class 的地方.

gen : 放系統資源檔、元件存放的地方. 當中的 R.java 是由 Android Development Kit (ADK) 所自動產生的資源索引檔(resource index). R.java 是根據 main.xml (在 res.layout中) 所自動產生,並不是由程式設計師編寫的,切勿修改此檔案

Android 1.1 : 放 Android Library的地方 (我使用的是1.1版).

res: 外部資源檔存放的位置, 可以設定文字、圖片、XML等,
其中的 layout : 存放畫面設定檔,values : 存放常數資源檔, drawable : 存放 icon圖片的地方.

例如: 若要調整畫面, 可以點開 layout, 會看到一個 mail.xml,
雙擊main.xml 則會開啟GUI畫面:
左上欄位 Layouts 為一層層的Layout
左 下欄位 Views 為各元件
下方則可以選擇要顯示 layout 或 mail.xml.
最下方有 Properties 的屬性設定視窗


各個 xml及java 都可以打開玩玩看. 這裡不多做說明.


每一個 Android 專案(package) 都會有 AndroidManifest.xml , 裡面說明這個 Android的程式具有哪些 Activity, Service 或 Receiver....


以上簡單說明 一個最單純的 Android Project (HelloWorld) 會包含哪些檔案.

2009年7月1日 星期三

Android 的第一個程式 Hello World

把Android的開發環境設完之後, 不免俗的要先測試一下可不可用.
大家應該都知道, "Hello World" 是每次學習一種新的開發軟體時, 要寫的第一個程式輸出.
在 wiki中也可以找到各種電腦語言輸出的 "Hello World" 的寫法. (可以到搜尋網站中找"Hello world program")
回正題.
開始建立 Hello World 專案:
在 Eclipse 中選 [File] --> [New] --> [Project]. 會開啟 New Project 視窗.
展開 [Android] 選 [Android Project] 之後按 [Next], 進入 New Android Project 視窗.
分別輸入下面資料:
Project name: HelloWorld
Build Target 選 Android 1.1 (應該也可以選其它的版本)
Application name: HelloWorld
Package name: helloworld.irdc.eracom.com.tw (這個是抄書上的, 應該也可以自行設定)
Create Activity: HelloWorld
(輸入各項欄位時, New Android Project 的 下面會提示輸入時的注意事項.)
然後按 [Finish]. 專案建立完成.
接著就是執行這個新程式.
點開 [Package Explorer] (在[Window] --> [Show view]中).
選 HelloWorld (目前應該只有這個) 按滑鼠右鍵 選 [Run As] --> [2. Android Application]
Eclipse就會開啟預設的 Android 模擬器, (開機時間會有點久), 然後會執行剛剛的HelloWorld.
(這個5554模擬器啟動後要按 MENU 來 解除 Screen locked, 進入, 就會顯示如下圖)
哈!! 恭喜恭喜. 完成了第一個Android 程式.
要結束程式就和一般手機的使用方式一樣, 按下手機模擬器上的 退回鍵 <==.

安裝 Android 的開發環境

要進入Android世界, 首先就是要把開發環境準備好.
根據書上說明, 在我的 win xp 下, 要有下列幾項軟體工具:

1. Java Development Kit (JDK) v6.0 以上
2. Android SDK 1.0r2 以上
3. Eclipse IDE 程式.

以上3項可以分別在:
http://java.sun.com/javase/downloads/index.jsp
http://developer.android.com/index.html
http://www.eclipse.org/downloads/

中下載.

由於資訊科技日新月異, 軟體版本也更新的很快. 所以原廠提供的最新版本應該都和書上說的不同.
但因為不想冒太大風險, 所以我就盡量按照書上類似的的版本.
我採用的是:
jdk-6u14-windows-i586.exe (JDK 6 Update 14);
android-sdk-windows-1.5_r2.zip (Android 1.5 SDK, Release 2); (註:.1.1 r1好像有小問題, 先不研究)
eclipse-jee-ganymede-SR2-win32.zip (Eclipse IDE for Java EE Developers).

下載完畢後.接下來就是要安裝這些軟體:

JDK安裝還算容易, 點一點就完成了.也沒有特別修改它內定存放的目錄.
Android SDK及 eclipse 都只要解壓縮放到想放的目錄就可以了.
基本上我是放到 C:\android 及 C:\eclipse 上.

另外還要設定一下系統環境變數:
就是將 "C:\android\tools" 及 "C:\Program Files\Java\jdk1.6.0_14\bin" 加入windows系統變數的 path 中.
設定的步驟: [我的電腦] -->[內容]-->[進階]-->[環境變數]






接著就是要啟動 Eclipse.
開啟 Eclipse 不是那麼順利, 有個 error code的視窗出現. 程式沒辦法開啟. (書上沒有特別說明, 要注意些什麼是ㄚ!). 也許是因為我沒玩過 java 的開發環境也有關係.

錯誤訊息的第一行是:
JVM Terminated. Exit Code=-1.

好不容易在網路上找到解決的方式. 就是把 eclipse.ini 中的 "-Xmx512m" 改為 "-Xmx256m" .

改好後. 再次啟動就沒問題了.
進入 Eclipse 後還要做幾個設定:
剛進入時會問工作空間 workspace 的位置, 若沒問題就用內定的就好了.
Eclipse開啟後, 要先下載 Android Development Tools plugin.
下載的步驟:
[help]--> [Software Updates] --> [Available Software] --> 右邊的[Add Site]
在 Location 填寫 https://dl-ssl.google.com/android/eclipse 按 [OK] 後 Available Software 就增加選項, 再將 Android DDMSAndroid Development Tools 選擇打勾, 按[Install] 安裝.
安裝完畢後, 會要重新啟動. 這樣 ADT 就安裝啟用完成了.

在正式建立 Android 專案之前, 要先設定一下 Android SDK的路徑:
[Windows]--> [Preferences] --> 左邊選 Android --> 按[Browse..] 選擇原先放置 Android的目錄 (我的是 C:\android ).
確定後 按 [Apply] , [OK] 就完成設定了.

這樣就可以開始正式建立 Android 專案了.