|
From: | Frederik Seiffert |
Subject: | Re: Android app using GNUstep |
Date: | Tue, 13 Oct 2020 12:18:47 +0200 |
Do you have an opensourced example for using the Java-ObjC bridge? Not at the moment, but here’s the method for registering ObjC blocks as native JNI callbacks via MABlockClosure if that helps: - (void)registerCallback:(NSString *)javaMethodName withSignature:(NSString *)signature usingHandler:(id)handler { MABlockClosure *blockClosure = [[MABlockClosure alloc] initWithBlock:[handler copy]]; JNINativeMethod nativeMethod = { .name = javaMethodName.UTF8String, .signature = signature.UTF8String, .fnPtr = blockClosure.fptr }; QAndroidJniEnvironment env; env->RegisterNatives(self.jcls, &nativeMethod, 1); if (env->ExceptionCheck()) { env->ExceptionDescribe(); env->ExceptionClear(); env->FatalError([NSString stringWithFormat:@"%@: failed to register bridge callback for '%@' with signature '%@'", self, javaMethodName, signature].UTF8String); } if (!self.blockClosures) { self.blockClosures = [[NSMutableDictionary alloc] init]; } self.blockClosures[javaMethodName] = blockClosure; } In order to associate Java objects with ObjC objects, we add a "private long objcObject" field to the Java object to store the pointer to the ObjC object. We can then read that field in the JNI callback in order to get the ObjC object that should handle the callback. When initializing Java objects from ObjC via JNI, we first allocate the object via AllocObject(), then call SetLongField() to set the objcObject field, and only then call the object’s init method. That way any native callbacks will also work during init. It’s all not very pretty but works well as long as you carefully manage the lifetimes of the ObjC and Java objects... Hope that helps and let me know if I can provide any further details! Frederik
|
[Prev in Thread] | Current Thread | [Next in Thread] |