this is my gluon attach service (under folder native/android/dalvik/)
package com.gluonhq.helloandroid;
import android.app.Activity;
import android.util.Log;
public class DalvikSmsService {
private final Activity activity;
public DalvikSmsService(Activity activity) {
this.activity = activity;
}
public static void receiveSms(String phone, String sms) {
processReceivedSms(phone, sms);
}
private native static void processReceivedSms(String key, String value);
}
with a corresponding JNI sms.c (under native/android/c/)file as below
#include "util.h"
// ... other handle declarations ...
JNIEXPORT jint JNICALL
JNI_OnLoad_sms(JavaVM *vm, void *reserved)
{
ATTACH_LOG_INFO("JNI_OnLoad_sms called");
#ifdef JNI_VERSION_1_8
JNIEnv* graalEnv;
if ((*vm)->GetEnv(vm, (void **)&graalEnv, JNI_VERSION_1_8) != JNI_OK) {
ATTACH_LOG_WARNING("sms error initializing native Sms from OnLoad");
return JNI_FALSE;
}
ATTACH_LOG_FINE("[sms service] Initializing native Sms from OnLoad started");
initializeGraalHandles(graalEnv);
initializeDalvikHandles();
ATTACH_LOG_FINE("[sms service] Initializing native Sms from OnLoad done");
return JNI_VERSION_1_8;
#else
#error Error: Java 8+ SDK is required to compile Attach
#endif
}
JNIEXPORT void JNICALL Java_com_gluonhq_helloandroid_DalvikSmsService_processReceivedSms
(JNIEnv *env, jclass service, jstring jkey, jstring jvalue)
{
// ... additonal code not show ...
}
When I load the apk and run the app, the sms service is loaded, BUT when I try to call DalvikSmsService.receiveSms('', 'sample sms'); the method is called but with the following error ...
AndroidRuntime: java.lang.UnsatisfiedLinkError: No implementation found for void com.gluonhq.helloandroid.DalvikSmsService.processReceivedSms(java.lang.String, java.lang.String) (tried Java_com_gluonhq_helloandroid_DalvikSmsService_processReceivedSms and Java_com_gluonhq_helloandroid_DalvikSmsService_processReceivedSms__Ljava_lang_String_2Ljava_lang_String_2)
The call from JNI (sms.c
):
static void initializeGraalHandles(JNIEnv* env) {
...
jGraalReceiceSmsMethod = (*env)->GetStaticMethodID(env, jGraalSmsClass, "receiveSms", "(Ljava/lang/String;Ljava/lang/String;)V");
}
JNIEXPORT void JNICALL Java_com_gluonhq_helloandroid_DalvikSmsService_processReceivedSms
(JNIEnv *env, jclass service, jstring jkey, jstring jvalue)
{
...
ATTACH_LOG_FINE("[sms service] call dalvik->native layer all got sms, key: %s, value: %s", keyChars, valueChars);
...
(*graalEnv)->CallStaticVoidMethod(graalEnv, jGraalSmsClass, jGraalReceiceSmsMethod, jKeyChars, jValueChars);
...
}
to to Java (AndroidSmsService.java
):
public static void receiveSms(String phone, String sms) {
Platform.runLater(() -> messages.add(new Message(phone, sms)));
}
actually uses reflection.
Currently, when the method is invoked, there is a SIGSEGV:
08-12 16:51:22.346 29215 29246 D GluonAttach: [sms service] Initializing native Sms from OnLoad started
08-12 16:51:22.346 29215 29246 D GraalGluon: ATTACH_DALVIK, tid = 29246, existed? 1, dalvikEnv at 0x7845064540
08-12 16:51:22.346 29215 29246 D GluonAttach: Util :: Load className com/gluonhq/helloandroid/DalvikSmsService
08-12 16:51:22.347 29215 29246 D GraalGluon: ATTACH_DALVIK, tid = 29246, existed? 1, dalvikEnv at 0x7845064540
08-12 16:51:22.351 29215 29246 I DalvikSmsService: sms receiced, phone: 123, sms: 456
08-12 16:51:22.351 29215 29246 D GluonAttach: [sms service] native layer got sms, key: 123, value: 456
08-12 16:51:22.351 29215 29246 D GraalGluon: ATTACH_GRAAL, tid = 29246, existed? 1, graalEnv at 0x7845064400
08-12 16:51:22.351 29215 29246 D GluonAttach: [sms service] call dalvik->native layer all got sms, key: 123, value: 456
--------- beginning of crash
08-12 16:51:22.352 29215 29246 F libc : Fatal signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x20 in tid 29246 (Thread-3), pid 29215 (ples.hellogluon)
08-12 16:51:22.463 29410 29410 I crash_dump64: obtaining output fd from tombstoned, type: kDebuggerdTombstone
08-12 16:51:22.468 835 835 I /system/bin/tombstoned: received crash request for pid 29246
08-12 16:51:22.469 29410 29410 I crash_dump64: performing dump of process 29215 (target tid = 29246)
08-12 16:51:22.480 29410 29410 F DEBUG : *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
08-12 16:51:22.480 29410 29410 F DEBUG : Build fingerprint: 'google/marlin/marlin:10/QP1A.191005.007.A3/5972272:user/release-keys'
08-12 16:51:22.480 29410 29410 F DEBUG : Revision: '0'
08-12 16:51:22.480 29410 29410 F DEBUG : ABI: 'arm64'
To prevent the crash, you just need to include the method receiveSms
in the jniconfig-aarch64-android.json
file under src/main/resources/META-INF/substrate/config/jniconfig-aarch64-android.json
:
[
{
"name" : "org.jpereda.attach.sms.impl.AndroidSmsService",
"methods":[
{"name":"receiveSms","parameterTypes":["java.lang.String","java.lang.String"] }
]
}
]
That works for me with GluonFX 1.0.4 and Gluon's GraalVM 21.2.0.