1. 程式人生 > >修改L版本android.jar使其包含增加的api

修改L版本android.jar使其包含增加的api

工作的時候有時候會在系統中增加api方法,這時候如果提供給app開發人員使用的話有兩種方法:

  1. 打包新的android.jar
  2. 使用反射

這裡簡單的說一下第一種方法,使用反射的方法可以參照之前的文章

其實android系統內帶的framework.jar已經包含了增加的api,只需將其抽取並放到官方的android.jar內就好了,整理一下就是:

  1. 增加新的方法make後,拷貝出新的framework.jar
  2. 解壓framework.jar,使用d2j-dex2jar.sh將其中的dex解壓為class檔案
  3. 解壓andoid.jar檔案
  4. 將步驟2中解壓出來的class檔案拷貝到步驟3解壓出來資料夾的對應位置
  5. 打包新的andoid.jar

方便起見,寫一個指令碼來完成上面的工作,其中轉換framework.jar用到dex2jar工具,請自行下載配置

#!/bin/sh
####################################################################################
##
## Usage: makesdk.sh framework.jar android.jar ~/Desktop
##
## 20170712 write by liuxq
## ## version 1.0 ## ## used to merge platform.jar to android.jar for app ## ## ps:need dex2jar tool ## #################################################################################### DEX2JAR_PATH="/home/liuxiuquan/SynologyDrive/ubuntu/worktest/test_shell/android_51_anrdoidjar/dex-tools-2.1/d2j-dex2jar.sh"
DEX=$1 AJAR=$2 OUT=$3 doMerge() { echo param: DEX=${DEX} AJAR=${AJAR} OUT=${OUT} current_time=`date '+%Y%m%d_%H%M%S'` android_jar_name=android_${current_time}.jar echo $android_jar_name #1.unpack framework.jar and do d2j-dex2jar cp $DEX framework.zip unzip -q -o -d framework_dex_tmp framework.zip echo "STEP ONE DONE!" #run d2j-dex2jar cd framework_dex_tmp # find -maxdepth 1 -name "classes*.dex" -exec ${DEX2JAR_PATH} --force {} \; >/dev/null 2>&1 find -maxdepth 1 -name "classes*.dex" -exec ${DEX2JAR_PATH} --force {} \; find -maxdepth 1 -name "classes*.jar" -exec unzip -q -o -d framework_jar_tmp {} \; cd .. #2.unpack android.jar cp $AJAR android.zip unzip -q -o -d android-sdk android.zip echo "STEP TWO DONE!" #3.merge and pack cp -r -f framework_dex_tmp/framework_jar_tmp/* android-sdk/ cd android-sdk # zip -q -r $OUT/android-new.jar * jar -cf ${OUT}/${android_jar_name} . cd .. echo "STEP THREE DONE!" #4.clean rm android.zip rm framework.zip rm -rf android-sdk/ rm -rf framework_dex_tmp/ echo "STEP FOUR DONE!" echo "new android.jar is locate at $OUT/${android_jar_name}" } usage(){ #41 background color, 37 font color echo "Usage: \033[41;37m$0 framework.jar android.jar ~/Desktop/ \033[0m" echo "first param is framework.jar's path" echo "second param is android.jar's path" echo "last param is output's path" echo '\nDo these things:' echo '1.unpack framework.jar and do d2j-dex2jar' echo '2.unpack android.jar' echo '3.merge and pack' echo '4.clean\n' } if [ ! $# -eq 3 ]; then case $1 in -h|--help) usage ;; *) #41 background color, 37 font color echo "Usage: \033[41;37m$0 framework.jar android.jar ~/Desktop\033[0m" echo "Try $0 -h for more information." ;; esac else doMerge fi

使用也很簡單,將這段指令碼存為makesdk.sh並給予可執行許可權,然後使用

$ makesdk.sh framework.jar android.jar ~/Desktop/

執行完成後,即可在桌面上看到一個名為android_${current_time}.jar的檔案,這就是包含我們增加api的sdk了

備註:
一、如果執行d2j-dex2jar.sh的時候有如下報錯,則需要更新下dex2jar版本

Landroid/preference/MultiSelectListPreference$1;.onClick(Landroid/content/DialogInterface;IZ)V
java.lang.RuntimeException: can not merge I and Z
	at com.googlecode.dex2jar.ir.TypeClass.merge(TypeClass.java:100)
	at com.googlecode.dex2jar.ir.ts.TypeTransformer$TypeRef.updateTypeClass(TypeTransformer.java:174)
	at com.googlecode.dex2jar.ir.ts.TypeTransformer$TypeAnalyze.provideAs(TypeTransformer.java:780)
	at com.googlecode.dex2jar.ir.ts.TypeTransformer$TypeAnalyze.enexpr(TypeTransformer.java:659)
	at com.googlecode.dex2jar.ir.ts.TypeTransformer$TypeAnalyze.exExpr(TypeTransformer.java:719)
	at com.googlecode.dex2jar.ir.ts.TypeTransformer$TypeAnalyze.exExpr(TypeTransformer.java:703)
	at com.googlecode.dex2jar.ir.ts.TypeTransformer$TypeAnalyze.enexpr(TypeTransformer.java:698)
	at com.googlecode.dex2jar.ir.ts.TypeTransformer$TypeAnalyze.exExpr(TypeTransformer.java:719)
	at com.googlecode.dex2jar.ir.ts.TypeTransformer$TypeAnalyze.exExpr(TypeTransformer.java:703)
	at com.googlecode.dex2jar.ir.ts.TypeTransformer$TypeAnalyze.s1stmt(TypeTransformer.java:810)
	at com.googlecode.dex2jar.ir.ts.TypeTransformer$TypeAnalyze.sxStmt(TypeTransformer.java:840)
	at com.googlecode.dex2jar.ir.ts.TypeTransformer$TypeAnalyze.analyze(TypeTransformer.java:206)
	at com.googlecode.dex2jar.ir.ts.TypeTransformer.transform(TypeTransformer.java:44)
	at com.googlecode.d2j.dex.Dex2jar$2.optimize(Dex2jar.java:162)
	at com.googlecode.d2j.dex.Dex2Asm.convertCode(Dex2Asm.java:414)
	at com.googlecode.d2j.dex.ExDex2Asm.convertCode(ExDex2Asm.java:42)
	at com.googlecode.d2j.dex.Dex2jar$2.convertCode(Dex2jar.java:128)
	at com.googlecode.d2j.dex.Dex2Asm.convertMethod(Dex2Asm.java:509)
	at com.googlecode.d2j.dex.Dex2Asm.convertClass(Dex2Asm.java:406)
	at com.googlecode.d2j.dex.Dex2Asm.convertDex(Dex2Asm.java:422)
	at com.googlecode.d2j.dex.Dex2jar.doTranslate(Dex2jar.java:172)
	at com.googlecode.d2j.dex.Dex2jar.to(Dex2jar.java:272)
	at com.googlecode.dex2jar.tools.Dex2jarCmd.doCommandLine(Dex2jarCmd.java:108)
	at com.googlecode.dex2jar.tools.BaseCmd.doMain(BaseCmd.java:288)
	at com.googlecode.dex2jar.tools.Dex2jarCmd.main(Dex2jarCmd.java:32)

引用下 https://github.com/pxb1988/dex2jar/issues/10 上pxb1988的回覆:

the problem is caused by strict type calculation, because in java syntaxt, a boolean can not assign to an inteager. so dex2jar forbid merge type Z and I. There are two solutions:

1.modify the dex by hand and add the following code after move-result v1

if-eqz v1, :LZERO
    const v1, 1
goto :Lend :LZERO
    const v1, 0 :Lend 

2.modify the dex2jar code. return Type I when merge I and Z at
com.googlecode.dex2jar.ir.TypeClass.merge(TypeClass.java:100)

二、其實也可以直接編譯android.jar,只是改動比較多。

$ source build/envsetup.sh 
$ launch'what you want'
$ make update-api
$ make PRODUCT-sdk-sdk -j8

程式碼使用android L

參考文章:
http://blog.sina.com.cn/s/blog_68b671430101nm3w.html