highlight.js

星期四, 8月 16, 2012

OOXX, Eclipse 中 R.java 就是不更新!

根據我估狗的結果, 顯然許多人都遇過這個問題, 比方說你在 res/layout 中加個新的 layout 檔, 或是改了某個資源的 Id, 可是 R.java 中這個新的 layout 檔就是不出現, 更改的 Id 名稱也不會更改變數名稱, 真的是不知道背後發生什麼事!

遇到這種狀況, 可以試試看使用 Project/Clean 功能表指令清理一下專案, 或者是更暴力一點, 把 R.java 刪除, 這兩個舉動都會重新產生 R.java 檔, 一般來說, 這樣就會根據目前的資源內容產生正確的 R.java 了。

星期三, 8月 15, 2012

android:minSdkVersion、android:targetSdkVersion、Project Build Target 的區別

初學 Android 的人在 Eclipse 裡建專案時, 看到這個建立新專案的精靈視窗, 常常會搞不懂中間 Build SDK 與 Minimum Required SDK 這兩個欄位的意義:

簡單來說, Minimum Required SDK 是宣稱此專案至少要在哪一個版本的 Android 系統上才能跑, 這裡選擇的值會出現在專案中 AndroidManifest.xml 檔中的 uses-sdk  元素中:
<uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="15" />
其中 android:minSdkVersion 屬性值就是上圖中 Minimum Required SDK 欄位的設定值。要特別注意的是, 這裡 SDK 版本都是以所謂的 API Level 值來指定, 而不是版本號碼, 例如圖中 Android 2.2 的 API Level 就是 8, 所以設定的值是 8, 而不是 2.2。

要特別說明的是, 這個設定值會影響 Google Play 是否將此程式顯示在商店中, 如果使用者裝置的 Android 版本比程式中這一項設定值指定的版本低, 此程式就不會出現在  Google Play 商店中。實際在執行程式時, 系統也會檢查此項設定值, 若是系統版本比程式的設定值低, 也會禁止執行這個程式。不過要注意的是, 這個設定值是開發者所「宣稱」, 至於這個程式是不是真的可以在該版本的 Android 裝置上正確執行, 就是開發者要負責的事情。

那麼在上面精靈視窗中的 Build SDK 設定的又是什麼值呢?這指的是實際在編譯程式時要用那一個版本的程式庫。這就與你實際要使用的功能有關, 有些功能只有在特定版本才提供, 若程式要使用, 就必須指定 Build SDK 欄位值為該版本。這個設定值會記錄在專案中 project.properties檔案中:
# Project target.
target=android-10
 或者也可以透過專案的 Properties 視窗檢視:


前面提到 AndroidManifest.xml 檔時, 您可能有注意到在 uses-sdk 元素中除了 android:minSdkVersion 外還有一個屬性叫做 android:targetSdkVersion, 請特別留意, 這個 android:targetSdkVersion屬性值和 Build SDK 欄位值是兩個不同的值。android:targetSdkVersion 屬性值是開發者『宣稱』在特定版本平台上已測試過程式可以正確無誤的執行。你可能會覺得很疑惑, 那這個值和 android:minSdkVersion 屬性值有什麼差異?

這就要講到 Android 平台的演進了, 在 Android 的新版本中, 當遇到以舊版程式庫編譯的程式時, 可能會嘗試啟動某些相容性的處理, 以便在新系統的平台上不會因為版本的差異而讓程式出錯。舉例來說, 新版的 Android 因為支援大畫面的平板, 所以遇到舊版程式時, 有可能會自動做某些調整, 讓理論上是為小尺寸螢幕設計的程式顯示起來不會與大螢幕格格不入。當然這額外的處理有可能會影響到執行的效能, 如果開發者確認不用系統幫忙程式也不會有問題, 就可以設定 android:targetSdkVersion 屬性值, 強制系統就不要啟動相容性的處理。

綜合上述, 一般來說, android:targetSdkVersion >= Build SDK >= android:minSdkVersion, 這是因為既然宣稱至少要使用 android:minSdkVersion 設定的版本才能執行此程式, 那麼編譯時就會透過 Build SDK 使用 android:minSdkVersion設定版本或是更新版本的程式庫, 才能包含所需的功能;而這個程式有可能在往後新版的 Android 版本上正確執行, 所以 android:targetSdkVersion 設定的版本至少會是 Build SDK 指定的版本。

舉例來說, 若是 android:minSdkVersion 為 7、Build SDK 為 8、android:targetSdkVersion 為 10, 就表示這個程式至少要在 Android 2.1 的裝置上才能執行, 但程式編譯時是使用了 Android 2.2 的程式庫, 而且程式已經在 Android 2.3.3 上測試過顯示、執行皆正常。

android:targetSdkVersion 屬性值在建立新專案時並沒有欄位可以設定, 我自己測試的結果似乎預設值為最新版本的前一版, 例如目前是 Android 4.1, API Level 為 16, 所以預設值就會自動設為 15, 請務必依照實際測試狀況修改此屬性值。

從上述說明就衍生了一個重要的問題, 因為 Build SDK 設定值可能會大於 android:minSdkVersion 設定的版本, 因此開發者必需自行處理相容性的問題, 如果使用了較新版本的功能, 就必須在程式中檢查執行時的系統版本, 在比 Build SDK 版本低的系統中以其他的方式提供相同的功能, 或是甚至禁用該功能, 才不會讓舊版系統的使用者因為執行到系統不具備的功能而出錯。