• Java 快速开发几 MB 独立 EXE,写图形界面很方便


    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; 
    
    • 1

    就会自动搜索系统可用的 JRE,如果没有找到 JRE,会自动导入 java.jre.v8 扩展库,并自动安装 OpenJDK JRE v8 。

    如果您希望发布的软件自带 Java 运行时,或者指定 JRE 的版本,只要在 aardio 中导入其他版本 JRE 的扩展库就可以,例如运行

    import java.jre.v8ora
    
    • 1

    就可以自动绑定 Oracle Java 8 运行时,软件运行会自动查找用户电脑上符合要求的 JRE,如果没有找到会全自动地安装和部署好,开发者要做的,仅仅就是写几句代码,把 EXE 简单地分发给用户就可以了。

    当然,独立 EXE 也可以嵌入更小的 JRE,aardio 里提供了一个示例 JRE,只要简单的在代码中加入

    import java.jre.v6
    
    • 1

    就可以在软件中嵌入一个精简版的 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 如此简单,我们可以在 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();
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    Java 会在 CLASSPATH 指定的搜索目录下使用 Java 类名(替换’.‘为’')" 去查找类,这类似 Windows 到 %PATH% 环境变量下搜索文件。CLASSPATH 已默认添加 “/java/“以及”/java/*.jar” 在首次创建 Java 虚拟机以前,可用下面的函数添加目录到 CLASSPATH:

    java.addClassPath("/java/"); 
    
    • 1

    以上参数指定目录下的 *.jar 也会自动添加(不递归子目录)。

    也可以如下自内存或文件直接加载类,注意下面的路径前面的$操作符可将文件编译到代码中(发布后不再需要原文件)

    HelloworldApp = jvm.import("aardio.sample.HelloworldApp"
         ,$"\java\aardio\sample\HelloworldApp.class");
    
    • 1
    • 2

    以上文件路径前面的波浪线反斜杠(或斜杆)表示程序根目录(开发时一般指工程目录,发布后指启动EXE文件所在的目录)。

    ▶  Java 调用 aardio 函数

    示例:

    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()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    Java 类 HelloworldApp (在范例中可以找到)中如下声明 aardio 函数:

    static native String aardio(String code);
    
    • 1

    ▶  aardio 直接运行 jar 程序

    您仅需数句代码可以将 jar 导入 aardio 生成软件件。以 Java 编写的软件 FFDec 为例,原来只能自己去下载安装 JRE,现在不用这么做了,我用 aardio 写了个例子:

    import fsys.dlg;
    import java.ffdec;
    
    java.ffdec(
        fsys.dlg.open("*.swf|*.swf")
    )
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    这个扩展库 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\") )
        } 
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    ▶  aardio 调用 jar 的 main 函数

    我们还可以直接调用 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"})
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    ▶  Java 函数签名

    原本调用 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")
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    但是上面的函数签名一般可以省略,可以简化为下面的代码:

    HelloworldApp.main( {
      "aaa字符串数组1","bbb字符串数组2"
    } )
    
    • 1
    • 2
    • 3

    上面的示例需要的 Java 类,可以在 aardio 自带范例里找到:

  • 相关阅读:
    JUC相关面试题
    Java学习 --- lambda表达式
    可交互提示Snackbar
    ML.NET 3.0 增强了深度学习和数据处理能力
    redis分布式锁的应用
    Redis的安装和配置
    java计算机毕业设计智慧机场管理系统源码+数据库+系统+部署+lw文档
    Java标识符指什么呢?
    【Python学习】Day-032 Day-033 xpath;xml数据格式、多线程、线程池、常用命令
    【微服务】CentOS7 虚拟机 安装 Docker
  • 原文地址:https://blog.csdn.net/m0_70748381/article/details/126929914