Android項目管理之配置管理

Android項目管理之配置管理

在Android開發中難免會遇到一系列的配置管理,例如版本配置、數據庫版本號配置、預置數據配置、網絡接口配置、加密信息配置、日誌配置、異常捕獲配置等。本文將對這些內容給出一個較爲合理的解決方案。

首先:爲什麼需要這些配置信息呢?
1.版本配置:發佈版本的時候毋庸置疑,需要在每次發佈的時候修改版本號和版本名稱,提醒用戶升級也是根據版本號來判斷的,所以版本配置是必須的
2. 數據庫版本配置:每次對用戶版本的升級,如果涉及到數據庫變更,必須要升級數據庫,而數據庫的升級是由SQLiteHelper根據數據庫版本號來判斷 的,即數據庫自身保存了上一版本的數據庫版本號,如果此次傳入的版本號大餘自身的版本號,則對數據庫upgread,並將新的版本號存儲爲自身版本號。
3.預置數據配置:對於一個需要聯網獲取內容顯示給用戶的應用,如果首次用戶打開你的應用是在沒有網絡的環境下進行的,你的應用會呈現出什麼樣子呢?提供些預製數據吧,當然預置數據還可以包含更多信息,如設置信息等
4.網絡接口配置:爲了靈活地應對網絡接口的變更,對網絡接口進行配置應該是比較好的方法,當然,還可以配置多套網絡接口,例如調試地址、正式地址、測試地址等
5.加密信息處理:如果你在項目中需要對某些預製內容加密或者壓縮、而又希望開發的時候能夠以源碼的方式進行
6.日誌配置:你在不同的環境下希望日誌有不同的表現,例如在正式發佈後希望不要顯示日誌、調試時顯示debug日誌、測試時顯示warning日誌等
7.異常配置:是否希望開啓異常捕獲,並將異常信息反饋到你的服務器
二:如何配置?
1.對於1版本配置對於Android開發而言,需要在Manifest中進行
2.對於2數據庫版本配置、6日誌配置、7異常配置在/res/raw/system.properties(位置和文件名可以是任意的,個人推薦位置是這裏)中配置
3.對於3預置數據配置,可以建立一個單獨的文件,用於配置預置數據
4.對於4網絡接口配置,可以2方法和3方法配合使用,2中配置環境,3中配置接口詳細信息
5. 對於5加密信息處理,首先要保證發佈時信息被加密貨壓縮,其次要保證開發時不受影響,我們可以在項目的根目錄下建立一個文件夾,名稱隨便叫什麼,然後需要 加密或壓縮的文件放在這裏,如果壓縮或者加密工具比較小的話也可以放在這裏,執行壓縮或加密腳本,將內容結果拷貝到需要的位置
三:最佳實踐
對二中給出的配置做實際性的處理
1.版本配置
Manifest.xml
  1. <manifest xmlns:android="http://schemas.android.com/apk/res/android" 
  2.     package="xxx.xxx.xxx" 
  3.     android:versionCode="xxx" 
  4.     android:versionName="xxx" > 
2.數據庫版本,日誌及異常配置
/res/raw/system.properties
  1. #the output versioin 
  2. version:9 
  3. #appName 
  4. appName:xxx 
  5. #log open or close 
  6. log:true 
  7. #carch exception ;true catch , false not carch 
  8. exception:false 
  9. #database version,when database is modified  ,plus 1 
  10. dbversion:9 
 
在系統初始化的時候初始化基本配置信息
  1. /** 
  2.      * 系統參數初始化 
  3.      * 
  4.      * @param appllicationContext 
  5.      */ 
  6.     public static void initSystemProperties(Context appllicationContext) { 
  7.         InputStream is = appllicationContext.getResources().openRawResource( 
  8.                 R.raw.system); 
  9.         Properties properties = new Properties(); 
  10.         try { 
  11.             properties.load(is); 
  12.             Variable.versionCode = Integer.parseInt(properties.getProperty( 
  13.                     Common.VERSION, "1")); 
  14.             Variable.isLogOpened = Boolean.parseBoolean(properties.getProperty( 
  15.                     Common.LOG, "false")); 
  16.             Variable.dbVersion = Integer.parseInt(properties.getProperty( 
  17.                     Common.DBVERSION, "1")); 
  18.             Variable.appName = properties.getProperty(Common.APPNAME); 
  19.             Variable.dbchange = properties.getProperty(Common.DBCHANGE, ""); 
  20.             Variable.isExceptionOpened = Boolean.parseBoolean(properties.getProperty( 
  21.                     Common.EXCEPTION, "false")); 
  22.         } catch (IOException e) { 
  23.             Util.error(e.getMessage()); 
  24.         } finally { 
  25.             Util.closeStream(is); 
  26.         } 
  27.     } 
 
2.1DBHelper作爲單例,實例化時將數據庫版本號傳入
  1. public static DBHelper getInstance() { 
  2.         if (helper == null) { 
  3.             helper = new DBHelper(Variable.appllicationContext, DB_NAME, null
  4.                     Variable.dbVersion); 
  5.         } 
  6.         return helper; 
  7.     } 

2.2日誌
  1. /** 
  2.      * Common log 
  3.      * 
  4.      * @param tag 
  5.      * @param msg 
  6.      * @param level 
  7.      */ 
  8.     public static void log(String tag, String msg, int level) { 
  9.         if (Variable.isLogOpened) { 
  10.             String msgs = msg; 
  11.             String tags = tag; 
  12.             Exception e = new Exception(); 
  13.             StackTraceElement[] els = e.getStackTrace(); 
  14.             String logDetails = Common.PACKAGENAME; 
  15.             for (int i = 0, l = els.length; i < l; i++) { 
  16.                 if (els[i].getClassName().startsWith(Common.PACKAGENAME) 
  17.                         && !els[i].getClassName().equals(Util.class.getName())) { 
  18.                     logDetails = els[i].getFileName() + "->" 
  19.                             + els[i].getMethodName() + ":" 
  20.                             + els[i].getLineNumber() + " "
  21.                     msgs = logDetails + msgs; 
  22.                     if ("".equals(tags)) { 
  23.                         tags = els[i].getFileName().substring(0
  24.                                 els[i].getFileName().indexOf(".")); 
  25.                     } 
  26.                     break
  27.                 } 
  28.             } 
  29.             switch (level) { 
  30.             case Log.DEBUG: 
  31.                 Log.d(tags, msgs); 
  32.                 break
  33.             case Log.INFO: 
  34.                 Log.i(tags, msgs); 
  35.                 break
  36.             case Log.WARN: 
  37.                 Log.w(tags, msgs); 
  38.                 break
  39.             case Log.ERROR: 
  40.                 Log.e(tags, msgs); 
  41.                 break
  42.             default
  43.                 Log.d(tag, msgs); 
  44.                 break
  45.             } 
  46.         } 
  47.     } 
  48.  
  49.     /** 
  50.      * Simple log 
  51.      * 
  52.      * @param tag 
  53.      * @param msg 
  54.      */ 
  55.     public static void log(String tag, String msg) { 
  56.         log(tag, msg, Log.WARN); 
  57.     } 
  58.  
  59.     public static void log(String msg) { 
  60.         log("", msg); 
  61.     } 
  62.  
  63.     public static void info(String msg) { 
  64.         log("", msg, Log.INFO); 
  65.     } 
  66.  
  67.     public static void error(String msg) { 
  68.         log("", msg, Log.ERROR); 
  69.     } 
  70.  
  71.     public static void debug(String msg) { 
  72.         log("", msg, Log.DEBUG); 
  73.     } 

2.3異常
BaseActivity的onCreate方法中添加

 

  1. if(Variable.isExceptionOpened){ 
  2.             CrashHandler handler = CrashHandler.getInstance(); 
  3.             handler.init(getApplicationContext()); 
  4.             Thread.setDefaultUncaughtExceptionHandler(handler); 
  5.         } 
3.預置數據
/home/chenze/workspace/trunk/assets/init.json
推薦使用json格式,佔用小,易解析,這裏主要就是解析特定格式的數據,然後存不存儲看項目了,可以入庫等
 
4.網絡接口:
由上面的2和3看,思路基本就是這樣了,2.中配環境,3中配地址

5.加密和壓縮信息處理
須 知在Android項目打包過程中,Android的根目錄中除了創建項目時的文件夾,其他的內容都不會被打包進去,這樣我們就可以在根目錄中隨意存儲內 容了(當然不建議太多)。我這裏建立了一個general目錄,存放壓縮和加密的工具及需要壓縮和加密內容的源碼。爲了管理方便,建議寫一個腳本,執行後 自動將目標內容拷貝到目標地址。例如,在該目錄下新建一個數據庫變更腳本,執行加密命令後,將該腳本的加密後副本拷貝到/res/raw目錄下,當需要執 行數據庫升級腳本時,解密該內容並執行

總結:
本文主要討論了筆者自身在項目配置方面的管理經驗,當然這些內容有的是借鑑了同事的經驗,無論怎樣,主要提供一些爲了簡便開發和管理的思路。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章