Android APK 多渠道快速編譯

對於Android開發者而言,最麻煩的就是屏幕適配和需要打包多個渠道的包!



下面提供一個快速打包的方法。



1.不需要把渠道號放在manifest文件中
如果我們使用的渠道號沒有必要非放在manifest文件中,我們可以選擇放在工程的assets文件夾下,因爲這個文件夾被編譯之後是沒有改變的。
例如:
1)我們把渠道號放在/assets/channel/channel.txt文件中。
2)然後生成生成一個沒有簽名的包(可以使用eclipse生成,也可以使用ant編譯出一個未簽名的apk)
3)使用rar壓縮來進行解壓、修改渠道號、壓縮、簽名。

  1. rd unsignedAPK\ /s /q
  2. rd signedAPK\ /s /q
  3. md signedAPK\
  4. md unsignedAPK\
  5. for /f "tokens=1-2 delims=','" %%i IN (chid_list.txt)do winrar x Test.apk Test_temp\&&del Test_temp\assets\channel\channel.txt&&echo %%i>>Test_temp\assets\channel\channel.txt&&winrar a -afzip -ep1 -r0 %%j.apk Test_temp\*.*&&rd Test_temp\ /s /q&&copy %%j.apk unsignedAPK\&&del %%j.apk&&jarsigner -verbose -keystore sign -storepass pass -signedjar signedAPK\%%j.apk unsignedAPK\%%j.apk biween
  6. rd unsignedAPK\ /s /q
  7. pause



上面是一個批處理文件,其中Test.apk 是你的未簽名的包,chidlist.txt是你需要打包的渠道號列表(格式是:2401,Test2.4.1_2401,逗號前面的是渠道號,後面的是簽名後生成的文件名),sign 是你的證書文件,pass 是證書的密碼。



試試效果吧,只要把上面的準備工作完成,點擊批處理,基本幾百個包5分鐘之內就能打完。
注:批處理依賴WinRAR,需要先裝Winrar



2.對於必須要在manifest裏面加渠道號的
有些情況下必須要把渠道號放在manifest裏面,比如個人開發者需要加入廣告,而廣告提供方提供的庫是從manifest裏面讀取渠道號的。



這種情況下就沒有什麼好辦法了,只能ant編譯,但也可以做一些優化。
具體的ant環境搭建就不再多說了,需要用到一個for循環的庫。
具體的實現方案就是執行一遍編譯把所需要的class,資源,等等都編譯出來,然後你會發現在/bin/裏面也會有一個manifest,這個是ant編譯的時候直接從工程裏拷過來的,我們要做的就是修改這個manifest裏的渠道號,然後重新編譯資源包,再簽名等等。



下面是ant編譯的腳本:



  1. <property name="market_channels_names" value="2361:EOE" /><!-- 這是1個渠道號,用:分開的,如果多個都以這種形式用逗號分開 -->
  2. <!-- 版本號 -->
  3. <property name="app_version" value="2.4.1 />
  4. <!-- 簽名信息 -->
  5. <property name="key.store" value="證書" />
  6. <property name="key.alias" value="alias名稱" />
  7. <property name="key.store.password" value="密碼" />
  8. <property name="key.alias.password" value="alias密碼" />
  9. <!-- 編碼 -->
  10. <property name="encoding" value="UTF-8" />
  11. <property name="out.channel.dir" value="out_channel" />
  12. <!-- 導入編譯文件 -->
  13. <import file="build_ext.xml" />
  14. <!-- 把各種資源打包成apk -->
  15. <target name="rebuild"
  16. depends="-set-release-mode, -release-obfuscation-check, -build-apk, -post-package, -release-prompt-for-password, -release-nosign, -release-sign, -post-build"
  17. description="Builds the application in release mode.">
  18. </target>
  19. <!-- -build-setup -->
  20. <target name="-build-apk" depends="-build-setup,-package-resources">
  21. <!-- only package apk if *not* a library project -->
  22. <do-only-if-not-library elseText="Library project: do not package apk..." >
  23. <if condition="${build.is.instrumented}">
  24. <then>
  25. <package-helper>
  26. <extra-jars>
  27. <!-- Injected from external file -->
  28. <jarfile path="${emma.dir}/emma_device.jar" />
  29. </extra-jars>
  30. </package-helper>
  31. </then>
  32. <else>
  33. <package-helper />
  34. </else>
  35. </if>
  36. </do-only-if-not-library>
  37. </target>
  38. <target name="make" >
  39. <!-- 刪除並創建輸出文件夾(打包簽名好的文件) -->
  40. <delete dir="${out.channel.dir}"/>
  41. <mkdir dir="${out.channel.dir}" />
  42. <!-- 清空已編譯的文件,再編譯 -->
  43. <!-- -->
  44. <antcall target="clean" />
  45. <antcall target="release" />
  46.  
  47. <foreach target="modify_manifest_channels" list="${market_channels_names}" param="nameandchannel" delimiter="," />
  48. </target>
  49. <!-- 修改channel, Umeng channel, Adview channel, channel值爲2361對應腳本中的${channelname},Umeng channel, Adview channel值爲EOE對應腳本中的${channelkey} -->
  50. <target name="modify_manifest_channels" >
  51. <!-- 獲取渠道名字 -->
  52. <propertyregex override="true" property="channelname" input="${nameandchannel}" regexp="(.*):" select="\1" />
  53. <!-- 獲取渠道號碼 -->
  54. <propertyregex override="true" property="channelkey" input="${nameandchannel}" regexp=":(.*)" select="\1" />
  55. <replaceregexp flags="g" byline="false">
  56.  
  57. <regexp pattern="android:value=&quot;(.*)&quot; android:name=&quot;CHANNEL&quot;" />
  58.  
  59. <substitution expression="android:value=&quot;${channelname}&quot; android:name=&quot;CHANNEL&quot;" />
  60.  
  61. <fileset dir="${out.absolute.dir}" includes="AndroidManifest.xml" />
  62. </replaceregexp>
  63. <replaceregexp flags="g" byline="false">
  64.  
  65. <regexp pattern="android:value=&quot;(.*)&quot; android:name=&quot;UMENG_CHANNEL&quot;" />
  66.  
  67. <substitution expression="android:value=&quot;${channelkey}&quot; android:name=&quot;UMENG_CHANNEL&quot;" />
  68.  
  69. <fileset dir="${out.absolute.dir}" includes="AndroidManifest.xml" />
  70. </replaceregexp>
  71. <replaceregexp flags="g" byline="false">
  72.  
  73. <regexp pattern="android:name=&quot;AdView_CHANNEL&quot; android:value=&quot;(.*)&quot;" />
  74.  
  75. <substitution expression="android:name=&quot;AdView_CHANNEL&quot; android:value=&quot;${channelkey}&quot;" />
  76.  
  77. <fileset dir="${out.absolute.dir}" includes="AndroidManifest.xml" />
  78. </replaceregexp>
  79. <property
  80. name="out.release.file"
  81. location="${out.absolute.dir}/${ant.project.name}_${channelname}_${app_version}.apk" />
  82. <!-- 各版本輸出位置 -->
  83. <property
  84. name="out.final.file"
  85. location="${out.absolute.dir}/${ant.project.name}_${channelname}_${app_version}.apk" />
  86. <antcall target="rebuild" />
  87. <!-- 複製打包完的文件到渠道文件夾 -->
  88. <copy file="${out.final.file}" tofile="${out.channel.dir}/${ant.project.name}_${channelname}_${app_version}.apk"/>
  89. <!-- 刪除複製完成的文件 -->
  90. <delete file="${out.final.file}"/>
  91. <!-- -->
  92. <delete file="${out.absolute.dir}/${ant.project.name}-release-unsigned.apk" />
  93. <delete file="${out.absolute.dir}/${ant.project.name}-release-unaligned.apk" />
  94. </target>



通過上面的方法能夠提高一些打包的速度,但是也不是很快。



現在好點的打包方法介紹完了,如果哪位有更好的辦法,歡迎分享出來!

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