Java 寫的桌面軟體帶上執行時只有 6 MB,而且還是獨立 EXE 文 件,是不是難以置信?
想一想 Electron 沒寫多少功能就可能超過百 MB 的體積,Java 寫的桌面軟體算不算得上小、輕、快呢?
aardio 可以支援很多程式語言, Java 就是其中之一。
aardio + Java 可生成體積極小的獨立 EXE 檔案,可以記憶體載入 Java 編寫的 class 檔案,用 aardio + Java 生成的軟體,釋出時不需要攜帶 Java 執行時。
aardio 寫圖形介面很方便。例如僅 605 KB 的開源軟體 ImTip:
例如僅 755 KB 的開源軟體 Gif123:
aardio 開發的程式,相容XP,Vista,Win7,Win8,Win10,Win11...... 等所有系統。aardio 只支援 Windows 系統( macOS + Linux 桌面市場份額小於被遺忘的 Win8 ),同時也扔掉了跨平臺的沉重包袱(更輕量、更好地利用專用平臺優勢)。將需要跨平臺的程式碼用 Java 寫,這並不影響在 Windows 上可以使用 aardio 生成 EXE 檔案 。跨平臺與專有平臺工具並不衝突,可以相互結合。
預設只要在 aardio 中呼叫
import java;
就會自動搜尋系統可用的 JRE,如果沒有找到 JRE,會自動匯入 java.jre.v8 擴充套件庫,並自動安裝 OpenJDK JRE v8 。
如果您希望釋出的軟體自帶 Java 執行時,或者指定 JRE 的版本,只要在 aardio 中匯入其他版本 JRE 的擴充套件庫就可以,例如執行
import java.jre.v8ora
就可以自動繫結 Oracle Java 8 執行時,軟體執行會自動查詢使用者電腦上符合要求的 JRE,如果沒有找到會全自動地安裝和部署好,開發者要做的,僅僅就是寫幾句程式碼,把 EXE 簡單地分發給使用者就可以了。
當然,獨立 EXE 也可以嵌入更小的 JRE,aardio 裡提供了一個範例 JRE,只要簡單的在程式碼中加入
import java.jre.v6
就可以在軟體中嵌入一個精簡版的 JRE 6 執行時,這個 JRE 只有 6MB 多一點,而且可以生成獨立 EXE 檔案,甚至還能支援 Windows XP 這種古老的系統。Java 寫的桌面軟體帶上執行時只有 6 MB,而且還是獨立 EXE 文 件,是不是難以置信?!想一想 Electron 沒寫多少功能就可能超過百 MB 的體積,Java 寫的桌面軟體算不算得上小、輕、快呢?!
現代 Java 已經可以非常方便地生成精簡版的 JRE,所以你只要參考 java.jre.v6 的實現( 放心這個庫的原始碼只有幾行 ),就可以非常輕鬆地更換為其他 JRE 版本,並生成極小的 EXE檔案( 而且可以是獨立的 EXE檔案)。
好吧,我們來看幾個 aardio 自帶的 aardio + Java 範例( 可以直接執行 )。
首先請看下面 aardio 呼叫 Java 如此簡單,我們可以在 aardio 中直接匯入 Java 的類,建立 Java 物件,就像在 Java 程式碼中一樣使用它們。
import console; import java; //建立 Java 虛擬機器器 var jvm = java(); //匯入 Java 類 HelloworldApp = jvm.import( "aardio.sample.HelloworldApp"); //修改類的靜態成員變數 HelloworldApp.static_num = 996; //獲取類的靜態成員變數 console.log( HelloworldApp.static_num ); //直接用 Java 類建立 Java 物件,跟 Java 中一樣用就行 var helloworld = HelloworldApp(); //獲取物件的成員欄位值 console.log( helloworld.name ); //呼叫物件的方法 console.log( helloworld.test(1) ); //呼叫 main 函數,引數是字串陣列 var ret = HelloworldApp.main( {"aaa字串陣列1","bbb字串陣列2"} ); console.log(ret); console.pause();
Java 會在 CLASSPATH 指定的搜尋目錄下使用 Java 類名(替換'.'為'\')" 去查詢類,這類似 Windows 到 %PATH% 環境變數下搜尋檔案。CLASSPATH 已預設新增 "/java/"以及"/java/*.jar" 在首次建立 Java 虛擬機器器以前,可用下面的函數新增目錄到 CLASSPATH:
java.addClassPath("/java/");
以上引數指定目錄下的 *.jar 也會自動新增(不遞迴子目錄)。
也可以如下自記憶體或檔案直接載入類,注意下面的路徑前面的$操作符可將檔案編譯到程式碼中(釋出後不再需要原檔案)
HelloworldApp = jvm.import("aardio.sample.HelloworldApp"
,$"\java\aardio\sample\HelloworldApp.class");
以上檔案路徑前面的波浪線反斜槓(或斜杆)表示程式根目錄(開發時一般指工程目錄,釋出後指啟動EXE檔案所在的目錄)。
範例:
import console; import java; //建立 Java 虛擬機器器 var jvm = java(); //匯入 Java 類 HelloworldApp = jvm.import( "aardio.sample.HelloworldApp"); //為 Java 提供 Native API HelloworldApp.registerNative( function(env,jobject,jstring){ var code = jvm.parseString(jstring) //也可以用 owner.parseString(jstring) var func = loadcode(code) return jvm.string( func() ) },"aardio","string(string)" ) var helloworld = HelloworldApp(); console.log( "Java 函數返回值",helloworld.test_aardio() ); console.pause()
Java 類 HelloworldApp (在範例中可以找到)中如下宣告 aardio 函數:
static native String aardio(String code);
您僅需數句程式碼可以將 jar 匯入 aardio 生成軟體件。以 Java 編寫的軟體 FFDec 為例,原來只能自己去下載安裝 JRE,現在不用這麼做了,我用 aardio 寫了個例子:
import fsys.dlg; import java.ffdec; java.ffdec( fsys.dlg.open("*.swf|*.swf") )
這個擴充套件庫 java.ffdec 的原始碼只有幾句:
import fsys; import java; import string.cmdline; namespace java; class ffdec { ctor( ... ){ var args = { "-Xmx1024m", "-Djna.nosys=true", "-Dsun.java2d.uiScale=1.0", "-jar",jarPath } ..table.append( args, ..string.cmdline.arguments(...)) return ..java.popenProcess( args,{workDir=..io.fullpath( self.workDir : "/")} ); } } namespace ffdec{ jarPath = ..io.appData("\aardio\std\java\ffdec\ffdec.jar"); if(!..io.exist(path)){ import sevenZip.lzma.tar; sevenZip.lzma.tar($"~\lib\java\ffdec\.res\ffdec.tar.lzma",..io.appData("aardio\std\java\") ) } }
我們還可以直接呼叫 jar 的 main 函數來執行 Java 程式,以 YUICompressor 為例:
import java; import java.yuiCompressor; java.addClassPath("~\lib\java\yuiCompressor\.res\yuicompressor.jar") var jvm = java();
YUICompressor = jvm.import( "com.yahoo.platform.yui.compressor.YUICompressor");
var ret = YUICompressor.main({"d:\test.js", "-o","d:\testmin.js"})
原本呼叫 Java 函數要寫簽名,但這個簽名寫起來是有些累的。所以 aardio 已經把這個事情完全給優化掉了,aardio 呼叫 Java 一般不用再去寫簽名。
但是 aardio 仍然允許以宣告普通靜態 API 函數的語法指定 Java 函數簽名 —— 然後由 aardio 自動翻譯為 Java 函數簽名。
舉個例子:
import java; var jvm = java(); //匯入 Java 類 HelloworldApp = jvm.import( "aardio.sample.HelloworldApp"); //getMethod 用於獲取一個函數,引數 @2 指定函數簽名 var main = HelloworldApp.getMethod("main","string(string[])"); //通過宣告匯入的函數,如果引數是字串,可以把引數展開寫 var result = main("test1","test2")
但是上面的函數簽名一般可以省略,可以簡化為下面的程式碼:
HelloworldApp.main( { "aaa字串陣列1","bbb字串陣列2" } )
上面的範例需要的 Java 類,可以在 aardio 自帶範例裡找到: