【長青說安卓】系列專題(九):Java中的Feature――_第1頁
【長青說安卓】系列專題(九):Java中的Feature――_第2頁
【長青說安卓】系列專題(九):Java中的Feature――_第3頁
【長青說安卓】系列專題(九):Java中的Feature――_第4頁
【長青說安卓】系列專題(九):Java中的Feature――_第5頁
已閱讀5頁,還剩6頁未讀 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

1、JAVA 中的 “Feature” -Android 應(yīng)用開發(fā)中如何實現(xiàn)條件編譯第一研究所 張長青 2011-09-06 前言 一般情況下,源程序中所有的行都參加編譯。但有時 希望對其中一部分內(nèi)容只在滿足一定條件下才進行編譯, 即對一部分內(nèi)容指定編譯條件,這就是 “ 條件編譯 ” ( conditional compile。條件編譯的引入,可以將針對于不同硬件平臺或軟件 平臺的代碼,或不同功能模塊的代碼,編寫在于同一程序 文件中,從而方便程序的維護和移植。在進行軟件移植的 時候,可以針對不同的情況,控制不同的代碼段被編譯 , 從而實現(xiàn)不同的功能。條件編譯最大的好處就是易于維護,特別是在針對不

2、同產(chǎn)品進行版本控制的時候。因為代碼只有一份,不需要 同時維護多份代碼。 1、C/C+中的條件編譯 這個其實不用多提,大家已經(jīng)司空見慣了,簡單一過。#ifdef identifier #ifndef identifieryour codeyour code#else #elseyour codeyour code#endif #endif#if defined (expressin1your code1#elif expression2your code2#elseyour code3#endif2、Java中如何實現(xiàn)條件編譯 Java語言的歷史與 C/C+沒有任何關(guān)系,設(shè)計思想也不一樣,所以

3、設(shè)計之初就沒有引入該功能。但是既然條件編譯是有作用的,那么在 Java 中如何實現(xiàn)類似的功能呢?根據(jù) Java 編譯器的優(yōu)化和布爾常量 (final Boolean的機制, Java 也能夠提供條件編譯。對于條件表達式中 永遠為 false 的語句,編譯器將不對條件覆蓋的代碼段生成字節(jié)碼。final boolean bDebug=false;if (bDebug注意:必須是 final 類型的。如果 if(bDebug 中的代碼量大的話,你可以看看當 bDebug 設(shè)置為 “true” 、 “false” 時生成 class 文件大小有何變化?;蛘呤褂梅淳幾g工具將 class 文件反編譯一下,

4、就可以看出其中的奧秘了。2、Java中如何實現(xiàn)條件編譯(續(xù) 對于一個普通的 Java 應(yīng)用來說,如果你想靈活地配置以實現(xiàn)條件編譯的功能,可以定義一個純數(shù)據(jù)的配置類來控制。例如:/AppConfig.javapublic class AppConfig public static final boolean bDebug = true;public static final boolean bSupportDualMode = false;public static final boolean bSupportDualCard = false;然后在你的其他類中,直接使用這些 final 變量來

5、實現(xiàn)條件編譯。 /AppMain.javaimport AppConfig.javapublic class AppMainAppMain(if (AppConfig.bDebugcode block第 2節(jié)介紹的方法針對一個普通的 Java 應(yīng)用是 可行的,你可以通過定義不同的 AppConfig.java 文 件來編譯不同功能的應(yīng)用。但是,如果你的應(yīng)用 處于一個大的系統(tǒng)中,例如 Android 開源工程,你 還有以下三種方法可以選擇。1將同一個應(yīng)用放到不同的產(chǎn)品目錄中,通過makefile文件來控制編譯 產(chǎn)品時選擇那個應(yīng)用目錄來編譯;2將同一個Java文件加上不同的產(chǎn)品后綴,編譯時根據(jù)產(chǎn)品

6、名稱,選擇 相應(yīng)的Java文件進行編譯;3通過設(shè)置Android.mk中的LOCAL_OVERRIDES_PACKAGES變量,可以讓你 的應(yīng)用覆蓋所有其他同名的應(yīng)用。(例如Lunch和Lunch2,Gallery和Gallery3D等以上三種方法,都可以實現(xiàn)根據(jù)不同產(chǎn)品的需求,編 譯不同功能的應(yīng)用。但是也都有一個明顯的缺點,特別是 在應(yīng)用或者文件中大部分代碼都一樣的情況下,重復和冗 余就是不可避免的。時間一久、產(chǎn)品一多,就會造成代碼 不同步和不一致,平臺性的問題不能統(tǒng)一修復,不同產(chǎn)品 的代碼越改越亂,給維護帶來噩夢,也間接地增加了質(zhì)量 風險。這本應(yīng)該是配置管理應(yīng)該研究的課題,我們當然希望 從

7、流程的源頭上就加以區(qū)別,然后有完善的評審機制、有 專門的配置管理人員來合并和發(fā)布代碼,但對于我們目前 的開發(fā)流程,這些都是空想。難道我們真的束手無策了嗎?請看下一節(jié) 4、通過p文件實現(xiàn)條件編譯 Android知道大家在做系統(tǒng)移植的時候,肯定有自己 特有的屬性。雖然系統(tǒng)是開源的,但并不表示所有的配置 都是一樣的,每個產(chǎn)品編譯的時候都可以有自己特有的屬 性。所以工程中提供了一個 p 配置文件,這是一 個文本文件,里面放了一系列的 Key/Value鍵值對用于配置 系統(tǒng)屬性。這個配置文件的語法相當簡單,每一行代表一項獨立 的內(nèi)容, # 號開頭的行表示注釋,其他

8、的行都是標準的 Key/Value鍵值對,中間以 = 號相連。4、通過p文件實現(xiàn)條件編譯(續(xù) 以編譯模擬器的 Generic 版本為例, p 文件處 于以下位置(相對于工程根目錄:./build/target/board/generic/p里面的內(nèi)容如下:# p for generic sdk#rild.libpath=/system/lib/libreference-ril.sorild.libargs=-d /dev/ttyS0p文件中的內(nèi)容最終會被編譯到 p 文 件中,路

9、徑如下(相對于工程根目錄:./out/target/product/generic/system/p備注:p是由shell腳本生成,里面除了有p中的內(nèi)容,還增加了一些其 他內(nèi)容,腳本位于./build/tools/buildinfo.sh/SystemProperties.javapackage android.os;public class SystemPropertiespublic static final int PROP_NAME_MAX = 31;/Key字符串最大長度 31public static final int PR

10、OP_VALUE_MAX = 91;/Value字符串最大長度 91public static String get(String key, String def;public static int getInt(String key, int def;/獲取整型值public static boolean getBoolean(String key, boolean def;/獲取布爾值public static void set(String key, String val;/設(shè)置 Key 值4、通過p文件實現(xiàn)條件編譯(續(xù) 好了,講了這么多,該開始實戰(zhàn)演練了。那么如何通

11、 過 p 文件中的屬性實現(xiàn)條件編譯呢?結(jié)合前面的 知識,下面用一個例子來展示我們的方法。需求:通過配置 p 中的屬性,來實現(xiàn) Gallery 應(yīng)用是否支持藍牙發(fā)送的功能。操作步驟:1在 p 文件中增加以下內(nèi)容:#Gallery App Properties2編譯工程,確保生成的 p 文件中已存在以 上內(nèi)容。4、通過p文件實現(xiàn)條件編譯(續(xù)3 在 Gallery.java 文件中增加以下內(nèi)容:public final class Gallery extends Activitypublic void

12、onCreate(Bundle savedInstanceState/* 以下代碼模擬條件編譯功能 */if (bSupportBluetoosh code blockelsecode block備注:用于控制條件的變量必須設(shè)置成 備注:用于控制條件的變量必須設(shè)置成static static static和 和 final final的, 的, 的,static static static表示是類共有的,而不 表示是類共有的,而不 需要每個對象創(chuàng)建一份,節(jié)省空間。 需要每個對象創(chuàng)建一份,節(jié)省空間。final final final表示是一旦初始化就不再修改,可以有利 表示是一旦初始化就不再修改

13、,可以有利 于編譯器的優(yōu)化。4、通過p文件實現(xiàn)條件編譯(續(xù)怎么樣,只要三個步驟就可以實現(xiàn)類似條件編譯的功 能,使用起來還比較簡單吧。但是,大家使用的過程中肯 定還會遇到問題,下面先分享幾個常見問題:1如果你編譯的不是Generic版本,那么p文件在哪里呢,可能是以下位置(在相應(yīng)的產(chǎn)品目錄下:./device/qcom/msm8960/p./device/qcom/msm7627a/p./device/qcom/msm7627_surf/p2修改p文件后,編譯前需要先刪除生成的

14、p文件,因為目前的編譯 系統(tǒng)對于已經(jīng)存在的文件不重新生成。文件可能在以下位置:./out/target/product/Product_XXX/system/p#LOCAL_SDK_VERSION := current備注:因為 備注:因為 備注:因為SystemProperties SystemProperties SystemProperties是非標準的 是非標準的 是非標準的SDK SDK SDK接口,如果要使用,不能定義 接口,如果要使用,不能定義 LOCAL_SDK_VERSIONLOCAL_SDK_VERSION變變 量。該變量表示應(yīng)用只使用標

15、準的 SDK SDK接口。接口。4、通過p文件實現(xiàn)條件編譯(續(xù)建議編寫 p 文件遵循幾個原則:1只定義功能性的屬性,不定義產(chǎn)品性的屬性;2 key值使用類似網(wǎng)址的方式分層定義,例如:說明:ro=read only,Gallery表示Gallery應(yīng)用,后面是具體的功能。 3 如果該功能只和某個應(yīng)用有關(guān),建議增加應(yīng)用的標識,如果和多個 模塊有關(guān),可以增加系統(tǒng)的標識,例如:4 key的字符串最大長度不能超過31,Value的最大長度不能超過91;總結(jié) 至此,本期的內(nèi)容就講完了,給大家介紹了一種可以 在Android系統(tǒng)開發(fā)中實現(xiàn)條件編譯的方法。除非必要,我 們不希望大家使用太多,我們?nèi)匀幌M覀兊膽?yīng)用和代碼 能是通用的,是能夠放之四海而皆準的。 夢想著有一天,我們的設(shè)計不再跟隨需求而變化,而 是用戶的需求隨著我們的設(shè)計而變化,就像 iPhone,但目 前這只是一個夢想。 生活還要繼續(xù)! 后面的話 最近我們正在如火如荼地學習 Android開發(fā)、學習Java 語言、學習面向?qū)ο缶幊?,對于我們這些從 C/C+轉(zhuǎn)型過 來的工程師來說,肯定會經(jīng)歷一個陣痛期。因為這不僅僅 是幾個Java語法的差異,而是一整套思維體系的轉(zhuǎn)變,我 們

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
  • 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論