使用Android Studio開發可獨立運行(runnable)混淆過的Jar程序
之前開發Java程序一直都是使用Eclipse 開發Jar程序,現在開發基本上都已經棄用Eclipse了,但是有時偶爾開發個小的Jar程序,還要切換回去好麻煩,剛好前幾天有人問幾個相關的問題,就順便整理了下Android Stuido開發Jar程序的一個簡單流程,方便后續開發需要。
創建工程
啟動Android Studio,新建一個Android Studio項目,如下圖
在彈出的項目配置框中填寫項目的名稱、包名、代碼路徑等信息,然后點擊下一步,如下圖。
選擇一個項目類型,最簡單的就是手機和平板應用了,然后其余的參數都不用修改,直接下一步,如下圖:
選擇不含任何Activity的項目,如下圖:
因為我們并不是要新建一個Android 應用,只是需要一個殼。之后點擊finish,然后就開始項目創建,如果個人的網絡環境無法代理到外網,可以點擊取消,然后切換為個人本地的開發用gradle常見配置項。配置方法可以參考文檔: 終端基于gradle的開源項目運行環境配置指引 。構建中的一些錯誤,也可以參考文章 gradle常見錯誤解決方案 來解決。
創建項目
當創建好工程以后,接下來就是創建Jar程序對應的項目,Android Studio中通過創建不同的Module可以維護不同的Jar.
選擇 “File”->”New”->”New Module”,彈出新建module對話框,選擇Java Library,如下圖:
在彈窗的模塊配置框中填寫模塊響應的信息,然后點擊完成,如下圖:
至此就已經完成了一個新模塊的創建,同時在該模塊的java代碼目錄創建MyClas類,如下圖:
創建入口類
一個可運行的java程序,都需要一個Java入口類,入口類需要實現Main方法,由于只是寫一個demo,因此這里就修改MyClass,在運行時打印一行文本。代碼如下:
package com.bihe0832.jardemo; public class MyClass { public static void main (String[] args){ System.out.println("Hello, world! I'm zixie"); } }
然后在項目視圖,選擇MyClass,右擊選擇”Run ‘MyClass.main()’“,然后就看到在控制臺打印出了項目的執行結果。如下圖:
至此就可以在Android Studio完成項目的開發了。
編譯運行
上面只給出了怎么編輯和運行,當項目開發完成以后,怎么生成項目對應的jar呢?在開發過程中,如果仔細觀察會發現其實當我們可以運行jar程序的時候,在項目目錄的build/libs目錄下已經生成了對應的jar包,那這個jar是否可以用呢?
? JarDemoByAndroidStudio git:(master) ? cd libdemo/build/libs ? libs git:(master) ? ls libdemo.jar ? libs git:(master) ? java -jar ./libdemo.jar ./libdemo.jar中沒有主清單屬性
發現運行報錯很熟悉,意思就是找不到整個jar包中的函數入口類,接下來就介紹怎么添加版本號,入口類等配置。
在項目視圖中打開libdemo對應的build.gradle,按照如下修改:
apply plugin: 'java' jar{ //項目名,也是生成的jar的名字 baseName = "libdemo" //項目版本號,這部分內容會寫進manifest version = "1.0" //項目的manifest定義,其中就包含最關鍵的入口類定義 manifest{ attributes 'Main-Class': 'com.bihe0832.jardemo.MyClass' } } dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) }
修改以后再運行MyClass,此時再去看build/libs目錄,發現內容已經有了變化,而且此時的jar已經可以運行
? JarDemoByAndroidStudio git:(master) ? cd libdemo/build/libs ? libs git:(master) ? ls libdemo-1.0.jar libdemo.jar ? libs git:(master) ? java -jar libdemo-1.0.jar Hello, world! I'm zixie ? libs git:(master) ?
至此最基本的需求已經滿足了。
混淆出包
上面已經可以生成可以運行的jar了,已經可以滿足大部分需求。但是實際開發中我們可能還會遇到下面的兩個問題:
- 代碼混淆
- 我們想把jar輸出到指定目錄
為了解決這兩個問題,我們進一步優化下我們的構建腳本,在腳本添加了一個makeJar的task,添加后的構建腳本如下:
apply plugin: 'java' jar{ //項目名,也是生成的jar的名字 baseName = "libdemo" //項目版本號,這部分內容會寫進manifest version = "1.0" //項目的manifest定義,其中就包含最關鍵的入口類定義 manifest{ attributes 'Main-Class': 'com.bihe0832.jardemo.MyClass' } } dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) } task makeJar(type: proguard.gradle.ProGuardTask, dependsOn: "build") { // 未混淆的jar路徑 injars 'build/libs/'+ jar.baseName +'-'+ jar.version +'.jar' // 混淆后的jar輸出路徑 outjars './../'+ jar.baseName +'.jar' // 混淆協議 configuration './../proguard-rules.pro' }
同時在項目的根目錄添加了混淆規則proguard-rules.pro
-libraryjars <java.home>/lib/rt.jar # Java運行時 #常規的代碼混淆規則 -dontwarn org.** -keep class org.** { *;} -keep public class com.bihe0832.jardemo.MyClass { public static void main(java.lang.String[]); }
之后,我們直接在項目根目錄運行命令即可直接在項目根目錄生成對應的混淆后的可運行jar
? JarDemoByAndroidStudio git:(master) ? ./gradlew makejar Java HotSpot(TM) 64-Bit Server VM warning: ignoring option MaxPermSize=1g; support was removed in 8.0 Parallel execution with configuration on demand is an incubating feature. Incremental java compilation is an incubating feature. :libdemo:compileJava UP-TO-DATE :libdemo:processResources UP-TO-DATE :libdemo:classes UP-TO-DATE :libdemo:jar UP-TO-DATE :libdemo:assemble UP-TO-DATE :libdemo:compileTestJava UP-TO-DATE :libdemo:processTestResources UP-TO-DATE :libdemo:testClasses UP-TO-DATE :libdemo:test UP-TO-DATE :libdemo:check UP-TO-DATE :libdemo:build UP-TO-DATE :libdemo:makeJar BUILD SUCCESSFUL Total time: 1.376 secs ? JarDemoByAndroidStudio git:(master) ? java -jar ./libdemo.jar Hello, world! I'm zixie
使用JDGui查看,可以看到Jar也確實已經被混淆過了~
至此,我們就完成了所有關于使用Android Studio開發可以獨立運行的Jar程序的所有工作。
附錄
本文中設計到的所有代碼都已經放在github上,可以前往查看:
https://github.com/bihe0832/JarDemoByAndroidStudio
來自:http://blog.bihe0832.com/as-runnable-jar.html