Ant和JDK7構建Android應用

上半年用Android寫了個小應用,使用Ant構建,一直都跑得非常順利。突然有一天,生成的APK不能安裝了!在用豌豆夾安裝生成的APK時報了個錯:

安裝失敗:該應用簽名有問題,無法安裝,您可以嘗試用豌豆夾手機精靈完整版進行重試。

  一開始,我以爲是Debug版本和正式的keystore衝突造成的,結果即使把已安裝的應用刪了之後再安裝,仍然報錯……偶的神啊,我到底幹了啥?

  回想良久,貌似我只更新了JDK而已,安裝了JDK7。於是重設JAVA_HOME和PATH,使之指向JDK6,再重新用Ant構建——APK安裝成功。

  事實證明了Ant+JDK7構建的APK不能安裝,這引起了我的好奇心。我決定研究一下爲什麼不能。考慮到提示“簽名有問題”,所以我將兩個 APK用壓縮軟件打開,比較了一下META-INF中的東西,結果發現.SF文件內容有點區別,JDK6生成的那個,是用的SHA1摘要算法,而JDK7 生成的那個是用的SHA256。

  JDK7居然修改了jarsigner的默認算法!

  於是我嘗試用jarsigner,指定參數-digestalg SHA1,手工對APK進行了簽名。簽名後的APK可以成功安裝運行。

  既然如此,我認爲去修改下Android SDK的tools/ant/build.xml,把簽名那段配置加個參數就行了吧。沒想到一查Ant Document,signjar任務居然不支持指定算法的參數。

  B方案,用exec調用jarsigner來簽名好啦!

  1. <!-- <signjar 
  2.         jar="${out.packaged.file}" 
  3.         signedjar="${out.unaligned.file}" 
  4.         keystore="${key.store}" 
  5.         storepass="${key.store.password}" 
  6.         alias="${key.alias}" 
  7.         keypass="${key.alias.password}" 
  8.         verbose="${verbose}" /> --> 
  9. <exec executable="jarsigner" failonerror="true"> 
  10.     <arg line="-verbose -digestalg SHA1 -sigalg MD5withRSA" /> 
  11.     <arg line="-keystore ${key.store} -storepass ${key.store.password} -keypass ${key.alias.password}" /> 
  12.     <arg line="-signedjar &quot;${out.unaligned.file}&quot;" /> 
  13.     <arg line="&quot;${out.packaged.file}&quot; ${key.alias}" /> 
  14. </exec> 

  雖然B方案可行,但是我不甘心,決定上網搜搜,有沒有更好的解決辦法。一搜之下發現,原來還真有人要求Ant爲signjar任務添加digestalg和sigalg參數。不過這在1.8.2裏肯定是看不到了,一年了也沒見Ant有更新,也許下一個版本里會有吧。

  不過Google畢竟是強大的,當然更強大的是聰明的程序員,我還搜到了一個C方案,說起來,跟B方案異曲同工,就是定義一個叫signjarjdk7的宏,調用exec來實現——這和B方案沒啥區別,只是貌似改起來方便些:

  1. <macrodef name="signjarjdk7"> 
  2.     <attribute name="jar" /> 
  3.     <attribute name="signedjar" /> 
  4.     <attribute name="keystore" /> 
  5.     <attribute name="storepass" /> 
  6.     <attribute name="alias" /> 
  7.     <attribute name="keypass" /> 
  8.     <attribute name="verbose" /> 
  9.     <sequential> 
  10.         <exec executable="jarsigner" failonerror="true"> 
  11.             <!-- magic key --> 
  12.             <arg line="-verbose -digestalg SHA1 -sigalg MD5withRSA" /> 
  13.             <arg line="-keystore @{keystore} -storepass @{storepass} -keypass @{keypass}" /> 
  14.             <arg line="-signedjar &quot;@{signedjar}&quot;" /> 
  15.             <arg line="&quot;@{jar}&quot; @{alias}" /> 
  16.         </exec> 
  17.     </sequential> 
  18. </macrodef> 

  然後將後面調用signjar的地方改爲調用signjarjdk7。這個方便就方便在不用改參數,以後Ant支持digestalg和sigalg了了,改回來容易。

  1. <!-- <signjar --> 
  2. <signjarjdk7 
  3.         jar="${out.packaged.file}" 
  4.         signedjar="${out.unaligned.file}" 
  5.         keystore="${key.store}" 
  6.         storepass="${key.store.password}" 
  7.         alias="${key.alias}" 
  8.         keypass="${key.alias.password}" 
  9.         verbose="${verbose}" /> 

 

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