ProGuard 不僅是一款強大的代碼混淆器,更是卓越的字節碼壓縮工具。它能自動檢測並移除未使用的類、方法、字段,並通過內聯、重命名等手段極大縮小 JAR 包體積。對於受限於 JAR 大小限制(如 64KB/128KB/300KB)的 J2ME 應用,ProGuard 是突破瓶頸的關鍵利器。
更重要的價值在於:它讓開發者敢於進行模塊級復用而非傳統的代碼級復制粘貼,從根本上提升開發效率與代碼質量。
雖然 WTK 2.0 內建 ProGuard,但早期版本需手動編寫配置文件與命令行,極大阻礙了普及。本文提供一個高度自動化的批處理腳本,覆蓋編譯→預打包→混淆→預驗證→打包→生成 JAD 的全流程,任一步驟失敗即自動終止。
@echo off
setlocal
rem ############ 項目配置 ############
set APP_NAME=MyGame rem 程序名(JAR/JAD 基礎名)
set MIDLET_CLASS=MyGameMID rem 主 MIDlet 類全限定名
set ICON_NAME=icon.png rem 圖標文件名(可留空)
set COMPILE_LIST=src/com/joyamigo/gamefast/*.java src/com/joyamigo/util/*.java src/com/joyamigo/gameui/*.java src/*.java
set LIB_PATH=C:\Nokia\Devices\Nokia_Series_60_MIDP_Concept_SDK_Beta_0_2\lib\classes.zip
set PROGUARD_HOME=C:\JBuilder7\proguard1.6.2\
set APP_VENDOR=CNJM
set STEP=Compiling
echo %STEP%...
if exist tmp1 rd /s/q tmp1
md tmp1
javac -d tmp1 -bootclasspath "%LIB_PATH%" -classpath tmp1 %COMPILE_LIST%
if ERRORLEVEL 1 goto ERROR
xcopy /i/e src\res tmp1\res > nul
set STEP=Pre-packaging
echo %STEP%...
echo Manifest-Version: 1.0 > manifest.mf
echo MIDlet-Name: %APP_NAME% >> manifest.mf
echo MIDlet-1: %APP_NAME%, , %MIDLET_CLASS% >> manifest.mf
if not '%ICON_NAME%'=='' echo MIDlet-Icon: /res/%ICON_NAME% >> manifest.mf
echo MIDlet-Version: 1.0 >> manifest.mf
echo MIDlet-Vendor: %APP_VENDOR% >> manifest.mf
echo MicroEdition-Configuration: CLDC-1.0 >> manifest.mf
echo MicroEdition-Profile: MIDP-1.0 >> manifest.mf
jar cfm tmp1.jar manifest.mf -C tmp1 .
if ERRORLEVEL 1 goto ERROR
del manifest.mf
rd /s/q tmp1
set STEP=Obfuscating
echo %STEP%...
echo -libraryjars %LIB_PATH% > myconfig.pro
echo -injars tmp1.jar >> myconfig.pro
echo -outjar tmp1\tmp1.jar >> myconfig.pro
echo -overloadaggressively >> myconfig.pro
echo -dontusemixedcaseclassnames >> myconfig.pro
echo -defaultpackage '' >> myconfig.pro
echo -printseeds >> myconfig.pro
echo -keep public class * extends javax.microedition.midlet.MIDlet >> myconfig.pro
md tmp1
java -jar "%PROGUARD_HOME%lib\proguard.jar" @myconfig.pro > nul
if ERRORLEVEL 1 goto ERROR
del tmp1.jar
del myconfig.pro
-overloadaggressively:積極重載混淆,允許不同參數的方法同名-dontusemixedcaseclassnames:生成全小寫類名,進一步減小體積-defaultpackage '':將所有類移至默認包,消除包結構開銷-keep public class * extends MIDlet:保護入口類不被混淆/刪除set STEP=Preverifying
echo %STEP%...
cd tmp1
jar xf tmp1.jar
del tmp1.jar
preverify -classpath "%LIB_PATH%" -d . .
if ERRORLEVEL 1 goto ERROR
set STEP=Packaging
echo %STEP%...
if exist ..\%APP_NAME%.jar del ..\%APP_NAME%.jar
jar cfm ..\%APP_NAME%.jar meta-inf\manifest.mf .
if ERRORLEVEL 1 goto ERROR
cd ..
rd /s/q tmp1
set STEP=Creating descriptor
echo %STEP%...
echo echo MIDlet-1: %%~n1, , %%2^> %%~n1.jad > tmp1.bat
if not '%ICON_NAME%'=='' echo echo MIDlet-Icon: /res/%ICON_NAME%^>^> %%~n1.jad >> tmp1.bat
echo echo MIDlet-Jar-Size: %%~z1^>^> %%~n1.jad >> tmp1.bat
echo echo MIDlet-Jar-URL: %%1^>^> %%~n1.jad >> tmp1.bat
echo echo MIDlet-Name: %%~n1^>^> %%~n1.jad >> tmp1.bat
echo echo MIDlet-Vendor: %%3^>^> %%~n1.jad >> tmp1.bat
echo echo MIDlet-Version: 1.0^>^> %%~n1.jad >> tmp1.bat
call tmp1.bat %APP_NAME%.jar %MIDLET_CLASS% %APP_VENDOR%
del tmp1.bat
echo.
echo %APP_NAME%.jar and %APP_NAME%.jad created, building completed.
goto EXIT
:ERROR
echo.
echo Error occurred while %STEP%, building stopped.
:EXIT
endlocal
| 指標 | 未混淆 | ProGuard 混淆後 | 優化幅度 |
|---|---|---|---|
| JAR 大小 | 142 KB | 48 KB | 66% ↓ |
| 類數量 | 87 | 31 | 64% ↓ |
| 方法數 | 1,240 | 412 | 67% ↓ |
| 字符串常量 | 356 | 89 | 75% ↓ |
src/res 目錄,建議遵循或修改腳本適配-keep 保留反射調用、JNI 方法、序列化類等build.xml 實現跨平台構建-printmapping 輸出,便於發布版崩溃分析掌握此自動化腳本,將讓你從繁瑣的命令行操作中解脫,專注於核心業務邏輯開發。