Android 的 gluonfx nativePackage
gluonfx nativePackage for Android
如何为 classes 启用 multiDex,以便它们可以包含在 DexPathList 中或在 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 ...
这是android清单设置..
<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>
当短信落在 phone 上时我得到的错误如下 ..
无法实例化接收器 demo.services.SmsListener: java.lang.ClassNotFoundException: 在路径上找不到 class“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 代码开始这个广播 class 吗?
project structure
最初的问题是在将项目打包到最终 APK 之前,将 Java 代码添加到 Android 源。
修改 Android 项目
由于 gluonfx 插件还没有自动过程,这是一个手动过程:
运行 mvn -Pandroid gluonfx:build gluonfx:package
一次,将在 target/gluonfx/aarch64-android/gvm/android_project
.
下创建 Android 项目
将 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,添加新服务,publish/distribute Attach 的这个修改版本,但更好的是在 Attach 之外创建一个自定义 Attach 服务。
日志服务
此实验性 repository 包含一项新服务:LogService
,作为概念验证。
readme 已包含有关如何开始和使用此服务的说明。
构建服务
总结一下:
- 确保您遵循 requisites
- 克隆存储库
- 构建并发布到本地:
./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
在你的项目中使用日志服务
假设你是 运行 [HelloGluon](https://github.com/gluonhq/gluon-samples/tree/master/HelloGluon):
pom
将依赖项添加到 pom.请注意,官方 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
。因此,将其视为常规依赖,需要根据target添加平台依赖:
例如,对于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
project 之后,创建您自己的服务应该或多或少是简单的。
比较复杂的部分在Java(11+)/JavaFX/GraalVM和Java(7)/Android之间的通信,这里需要JNI。 Java 端是 AOT 编译并进入 lib${service}.a
并且 Android 端进入 Android 项目并作为 ${service}>.aar
分发,没有 Java外汇支持。
如何为 classes 启用 multiDex,以便它们可以包含在 DexPathList 中或在 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 ...
这是android清单设置..
<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>
当短信落在 phone 上时我得到的错误如下 .. 无法实例化接收器 demo.services.SmsListener: java.lang.ClassNotFoundException: 在路径上找不到 class“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 代码开始这个广播 class 吗? project structure
最初的问题是在将项目打包到最终 APK 之前,将 Java 代码添加到 Android 源。
修改 Android 项目
由于 gluonfx 插件还没有自动过程,这是一个手动过程:
运行
下创建 Android 项目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,添加新服务,publish/distribute Attach 的这个修改版本,但更好的是在 Attach 之外创建一个自定义 Attach 服务。
日志服务
此实验性 repository 包含一项新服务:LogService
,作为概念验证。
readme 已包含有关如何开始和使用此服务的说明。
构建服务
总结一下:
- 确保您遵循 requisites
- 克隆存储库
- 构建并发布到本地:
./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
在你的项目中使用日志服务
假设你是 运行 [HelloGluon](https://github.com/gluonhq/gluon-samples/tree/master/HelloGluon):pom
将依赖项添加到 pom.请注意,官方 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
。因此,将其视为常规依赖,需要根据target添加平台依赖:
例如,对于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
project 之后,创建您自己的服务应该或多或少是简单的。
比较复杂的部分在Java(11+)/JavaFX/GraalVM和Java(7)/Android之间的通信,这里需要JNI。 Java 端是 AOT 编译并进入 lib${service}.a
并且 Android 端进入 Android 项目并作为 ${service}>.aar
分发,没有 Java外汇支持。