APK編譯時自動帶上commit id版本標識


帶有commit id的版本描述

git describe可以顯示用戶友好的版本描述:
$ git describe --tags
0. 1. 34 - 3 -gab9f2b0
 
它的含義是:
1、當前HEAD位置前面一個tag是0.1.34。
2、當前HEAD在0.1.34 tag之后3個commit的位置。
3、當前HEAD對應的commit id是ab9f2b0。(g應該表示global,全局唯一的SHA)
 
參見下面的分支圖:
$ git lg - 5
* ab9f2b0 - (HEAD, origin /master, origin /HEAD, master) exit with status 0 when t
*   c99a2a9 - Merge pull request #210 from egeland/master (9 months ago) <Gabrie
|\  
| * 20ebe7a - Added Norwegian strings ( 9 months ago) <Frode Egeland >
| /  
* 388aa1d - ( 0. 1. 34) release 0. 1. 34 ( 9 months ago) <Gabriel Falcao >
 
注:
如果HEAD位置剛好有tag,則只顯示tag。
 

版本描述如何傳遞給應用代碼

如果是C/C++,可以在Makefile中定義宏來傳遞。
那么Java編寫的APK如何傳遞呢?
 
經過研究,較好的一種方式是通過AndroidManifest.xml中的meta-data。
 

在AndroidManifest.xml中增加hw_version的meta-data

     <application >
         <activity >
         < /activity >
         <meta -data android :name = "hw_version" android :value = "0.1.34-3-gab9f2b0" / >
     < /application >

在Java文件中讀取meta-data

import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;

     public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_test_app);

         try {
            ApplicationInfo appInfo = this.getPackageManager()
                                      .getApplicationInfo(getPackageName(), 
                              PackageManager.GET_META_DATA);
            String hwVersion =appInfo.metaData.getString( "hw_version");
            ((TextView)findViewById(R.id.hw_version)).setText( "Apk version is " + hwVersion);
            Log.i( "MyCamera", "The version of this apk is " + hwVersion);
        } catch (Exception ex) {
            Log.i( "MyCamera", "Get apk version failed.");
        }
    }

如何在Android編譯系統中自動生成hw_version

用sed替換版本號

首先固定在AndroidManifest.xml中默認設置hw_version為no-version。
在編譯的時候用sed命令替換成正確的版本描述。
$ sed -n 's/<meta-data android:name="hw_version" android:value=".*"/<meta-data android:name="hw_version" android:value="abcdef"/p' AndroidManifest.xml
         <meta -data android :name = "hw_version" android :value = "abcdef" / >

修改Android.mk自動查詢版本描述並更新AndroidManifest.xml

在Android.mk中 include $(BUILD_PACKAGE) 之前加上:
LOCAL_HW_VERSION : = $(shell git --git -dir =$(LOCAL_PATH) /.git describe --tags)
$(shell sed -i 's/<meta-data android:name="hw_version" android:value=".*"/<meta-data android:name="hw_version" android:value="$(LOCAL_HW_VERSION)"/' $(LOCAL_PATH) /AndroidManifest.xml)
 

自動生成應用版本號

Android應用的版本號一般定義在AndroidManifest.xml中,以android:versionName="1.1"的形式標識。
修改版本號,一般要修改該xml文件並上庫。
 
參見前面sed替換版本描述的方法,可以根據git倉最近的tag替換versionName。
比如,保留tag和相對tag的commit數量作為版本號:
$ git describe --tags
0. 1. 34 - 3 -gab9f2b0
 
如果當前HEAD位置就有tag,則得到的結果類似下面這樣:
$ git describe --tags
0. 1. 34
 
可以參考下面的sed正則表達式匹配只使用滿足條件的tag:(數字.數字.數字,分別為V版本、R版本、C版本)
$ echo "0.1.34-3-gab9f2b0" | sed -n -e "/^[0-9]\{1,\}\.[0-9]\{1,\}\.[0-9]\{1,\}\(-[0-9]\{1,\}-g[0-9a-f]\{7,\}\)\{0,1\}$/p"
0. 1. 34 - 3 -gab9f2b0
$ echo "0.1.34" | sed -n -e "/^[0-9]\{1,\}\.[0-9]\{1,\}\.[0-9]\{1,\}\(-[0-9]\{1,\}-g[0-9a-f]\{7,\}\)\{0,1\}$/p"
0. 1. 34
 
該正則表達式的說明如下:
^ 匹配字符串開始
[0-9]\{1,\}  匹配1個或多個數字
\.   匹配點。
\(-[0-9]\{1,\}-g[0-9a-f]\{7,\}\)\{0,1\}  commit相關信息出現0次或者1次。
$ 匹配字符串結束。
 
為了用戶更容易理解,可去掉最后面的commit id,並把相對於tag位置的commit數量以點連接起來,為了避免沒有commit id的時候末尾是個點,可總是補上一個0:
$ echo "0.1.34-3-gab9f2b0" | sed -n -e "s/^\([0-9]\{1,\}\.[0-9]\{1,\}\.[0-9]\{1,\}\)\(-\([0-9]\{1,\}\)-g[0-9a-f]\{7,\}\)\{0,1\}$/\1\.0\3/p"
0. 1. 34. 03
 
當按照上述方式得到的結果不為空,才替換versionName.
 
把這個思路實現到Android.mk中:
 
LOCAL_HW_VERSION_NAME : = $(shell echo $(LOCAL_HW_VERSION) | sed -n -e "s/^\([0-9]\{1,\}\.[0-9]\{1,\}\.[0-9]\{1,\}\)\(-\([0-9]\{1,\}\)-g[0-9a-f]\{7,\}\)\{0,1\}\$$/\1\.0\3/p")

ifneq (,$(strip $(LOCAL_HW_VERSION_NAME)))
$(shell sed -i 's/android:versionName=".*"/android:versionName="$(LOCAL_HW_VERSION_NAME)"/' $(LOCAL_PATH) /AndroidManifest.xml)
endif
 
說明:
Makefile中的$需要重復進行轉義。
 

Makefile修改重構優化

 
這么復雜而且可復用的處理直接寫在每個模塊的Android.mk中顯然是不好的,最好把它提取成函數,需要的地方調用一次即可。
於是,把它提取到 build/core/.mk 中,內容如下:
###########################################################
## Modify version info in AndroidManifest.xml
###########################################################

# Usage:
#   1. git tag n.m.x on the significant commit. (n, m, x are digitals)
#   2. call $(modify-hw-version) in Android.mk
#   3. make sure there is android:versionName or hw_version meta-data in AndroidManifest.xml

define modify -hw -version
    $(eval $(generate -hw -version))
endef

# 1. LOCAL_HW_VERSION is like 0.1.34-3-gab9f2b0, 
#             0.1.34  is tag name, 
#             3       is commit count from the tag, 
#             ab9f2b0 is the current commit id.
#
# 2. LOCAL_HW_VERSION_NAME is like 0.1.34.03
define generate -hw -version

$(eval LOCAL_HW_VERSION : = $(shell git --git -dir =$(LOCAL_PATH) /.git describe --tags))
$(shell sed -i 's/<meta-data android:name="hw_version" android:value=".*"/<meta-data android:name="hw_version" android:value="$(LOCAL_HW_VERSION)"/' $(LOCAL_PATH) /AndroidManifest.xml)

$(eval LOCAL_HW_VERSION_NAME : = $(shell echo $(LOCAL_HW_VERSION) | sed -n -e "s/^\([0-9]\{1,\}\.[0-9]\{1,\}\.[0-9]\{1,\}\)\(-\([0-9]\{1,\}\)-g[0-9a-f]\{7,\}\)\{0,1\}\$$/\1\.0\3/p"))
ifneq (,$(strip $(LOCAL_HW_VERSION_NAME)))
$(shell sed -i 's/android:versionName=".*"/android:versionName="$(LOCAL_HW_VERSION_NAME)"/' $(LOCAL_PATH) /AndroidManifest.xml)
endif

endef
 
此方案可圓滿解決版本號自動生成的問題,但編譯后AndroidManifest.xml被修改。這可能影響后續的git操作。
最好能有編譯的后處理,把AndroidManifest.xml還原。
 





免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM