x/mobile/cmd/gomobile: RunOnJVM is not available from init functions

gab6jxml  于 6个月前  发布在  Go
关注(0)|答案(6)|浏览(54)

在我的库中,JNI函数从Go端调用。通过全局C变量current_vm访问JVM。我承认依赖这个变量不是一个好方法,但从Go端访问JNI没有其他方法。实际代码是https://github.com/hajimehoshi/ebiten/blob/master/internal/jni/jni_android.go

我意识到当init函数被调用时,current_vm尚未初始化。据我了解,current_vm在调用活动的onCreate时初始化,而这个onCreate在所有init函数被调用并在main被调用之前被调用。

难道不能让JVM在init函数中可用吗?对于gomobile-bind,由于init函数在调用SetCurrentContext之前自动被调用,那么可能不可能。如果这是不可能的,那么从Go端调用JNI函数有其他方法吗?

至于iOS,通过cgo实现的Objective-C绑定是可用的,没有这样的问题。

vfwfrxfs

vfwfrxfs1#

golang/mobile@56e3592 无法访问 current_vm,这意味着直接调用 JNI 函数不再可用。:-/

pepwfjgg

pepwfjgg2#

上述问题已解决。顺便说一下,为了在init()函数中使用JNI,我也尝试过使用JNI_GetCreatedJavaVMs,但由于以下消息失败了。添加#cgo LDFLAGS: -ljvm没有帮助,因为libjvm找不到。

b91juud3

b91juud33#

我的理解是,Seq.setContext(gomobile-bind案例)试图初始化上下文并调用一个Go函数,但在设置上下文之前,这个调用触发了所有的init函数。为了解决这个问题,我们需要在没有Go的情况下设置上下文。这是正确的吗?
CC @hyangah@timcooijmans

xkrw2x1b

xkrw2x1b4#

对不起,我错过了这个问题。
是的,目前就是这样工作的。这个改变是必要的,因为较早版本的gomobile使用了被Android列入黑名单的反射。你真的必须使用init()函数吗?不能使用你自己的initX()函数吗?
你不必绑定到一个活动,你也可以从服务甚至从应用程序中进行操作。但我想这并不能解决你的问题。

w6mmgewl

w6mmgewl5#

你好,

你真的需要使用init()函数吗?不能使用自己的initX()函数吗?

我可能不需要,但其他人可能需要。我正在开发一个与gomobile一起工作的库。如果一个函数使用了RunOnJVM,那么这个函数可以在main之后调用,但不能在init中调用,这并不是一个好的用户体验。

c8ib6hqw

c8ib6hqw6#

https://github.com/golang/mobile/blob/35478a0c49da882188b186a3893d45be6ff74327/app/android.go#L72

相关问题