首页 > 解决方案 > 适用于 Android 的 gluonfx nativePackage

问题描述

如何为类启用 multiDex,以便可以在 DexPathList 中包含或跟踪它们?

我正在使用 graalvm(带有本机图像)和 gluonfx nativePackage 任务来生成 apk。

id 'com.gluonhq.gluonfx-gradle-plugin' version '1.0.3' //build.gradle

但是当我尝试访问 SMS BroadcastReceiver 时,我得到 Class not found in the DexPathList ...

这是 androidManifest 设置..

     <application ... package="demo"   ...>
        <uses-permission android:name="android.permission.RECEIVE_SMS"/>
        <receiver android:name=".services.SmsListener" 
                  android:enabled="true" 
                  android:exported="true"
                  android:permission="android.permission.BROADCAST_SMS">
            <intent-filter>
                <action android:name="android.provider.Telephony.SMS_RECEIVED"/>
            </intent-filter>
        </receiver>
     </application>

当手机上的短信掉线时我得到的错误如下.. 无法实例化接收器demo.services.SmsListener:java.lang.ClassNotFoundException:在路径上找不到类“demo.services.SmsListener”:DexPathList [ [zip 文件“/data/app/.../base.apk”],nativeLibraryDirectories=[/data/app/...-g==/lib/arm64, /data/app/..g==/ base.apk!/lib/arm64-v8a, /system/lib64, /system_ext/lib64]]

那么如何将 MultiDexEnabled True 传递给 android 任务呢?或者有没有办法通过java代码启动这个广播类? 项目结构

标签: javaandroidjavafxgluongraalvm-native-image

解决方案


最初的问题是关于将 Java 代码添加到 Android 源代码中,然后再将项目打包到最终的 APK 中。

修改安卓项目

由于 gluonfx 插件还没有自动过程,因此它是一个手动过程:

  • 运行mvn -Pandroid gluonfx:build gluonfx:package一次,将在target/gluonfx/aarch64-android/gvm/android_project.

  • 将 Java/Android 源代码添加到target/gluonfx/aarch64-android/gvm/android_project/app/src/main/java

  • 手动构建 APK:

    cd target/gluonfx/aarch64-android/gvm/android_project/
    export ANDROID_SDK_ROOT=~/.gluon/substrate/Android
    ./gradlew app:assembleDebug
    
  • 继续这个过程:mvn -Pandroid gluonfx:install gluonfx:run

虽然这允许修改 Android 部分,但主要的警告是缺乏从这一端到 Java/JavaFX/GraalVM 部分的通信,因此它仅在它是 Android 端的孤立修改的情况下才有效。

创建自定义附加服务

为了修改 Android 部分并访问 Java/JavaFX 端,最好的方法是创建一个Attach服务。

为此,一种选择是克隆 Attach,添加新服务,然后发布/分发这个修改后的 Attach 版本,但更好的是在 Attach 之外仅创建一个自定义 Attach 服务。

日志服务

这个实验性存储库包含一个新服务:LogService,就像概念证明一样。

自述文件已包含有关如何开始和使用此服务的说明。

构建服务

总结一下:

  • 确保您遵循要求
  • 克隆存储库
  • 构建并发布到本地:./gradlew clean publishToMavenLocal.
  • 确保您有以下工件~/.m2/repository/org/jpereda/attach/log/4.0.12-SNAPSHOT
   log-4.0.12-SNAPSHOT-android.jar
   log-4.0.12-SNAPSHOT-ios.jar 
   log-4.0.12-SNAPSHOT-desktop.jar
   log-4.0.12-SNAPSHOT.jar

在你的项目中使用 LogService

假设您正在运行 [HelloGluon](https://github.com/gluonhq/gluon-samples/tree/master/HelloGluon):
绒球

将依赖项添加到 pom.xml 中。请注意,官方的 Attach 依赖项保持不变,但您需要 4.0.12-SNAPSHOT。

<dependencies>
    <dependency>
        <groupId>com.gluonhq.attach</groupId>
        <artifactId>storage</artifactId>
        <version>4.0.12-SNAPSHOT</version>
    </dependency>
    ...
    <dependency>
        <groupId>org.jpereda.attach</groupId>
        <artifactId>log</artifactId>
        <version>4.0.12-SNAPSHOT</version>
    </dependency>
</dependencies>

<repositories>
        <repository>
            <id>snapshots</id>
            <url>https://oss.sonatype.org/content/repositories/snapshots</url>
        </repository>
    </repositories>

注意,由于不是官方的 Attach 服务,所以不能使用包名com.gluonhq.attach,也不能添加到attachList. 因此,它被视为常规依赖,需要根据目标添加平台依赖:

例如,对于 Android:

        <profile>
            <id>android</id>
            <properties>
                <gluonfx.target>android</gluonfx.target>
            </properties>
            <dependencies>
                <dependency>
                    <groupId>org.jpereda.attach</groupId>
                    <artifactId>log</artifactId>
                    <version>4.0.12-SNAPSHOT</version>
                    <classifier>android</classifier>
                    <scope>runtime</scope>
                </dependency>
            </dependencies>
        </profile>
代码

从您的代码中,照常调用该服务:

LogService.create().ifPresent(service -> service.log("This is a message"));

测试服务

例如,在 Android 上:

mvn -Pandroid gluonfx:build gluonfx:package gluonfx:install gluonfx:nativerun

创建自己的服务

首先,阅读https://docs.gluonhq.com/#_device_interface以更好地了解 Attach 服务。

LogService 项目之后,创建自己的服务应该或多或少简单。

更复杂的部分是 Java(11+)/Ja​​vaFX/GraalVM 和 Java(7)/Android 之间的通信,其中需要 JNI。Java 端是 AOT 编译并进入lib${service}.a,Android 端进入 Android 项目并分发为${service}>.aar,没有 JavaFX 支持。


推荐阅读