Golang中能否将Java的回调函数作为参数传递?

Golang中能否将Java的回调函数作为参数传递? 我的目标:我想从 Go 向 Java 发送数据。

我正在使用 gomobile bind 为 Android 生成绑定。我有一个用例,希望在 Go 中编写并导出一个函数,该函数接受一个简单的函数作为参数,如下所示:

func SetCallback(cb Callback)

其中 Callback 是一个用户定义的类型:

type Callback func(string)

然而,gomobile bind 无法为此函数生成 Java 绑定。我也尝试过不定义 Callback 类型直接这样做:

func SetCallback(cb func(string))

但没有成功。是否有其他方法可以实现这个功能?


更多关于Golang中能否将Java的回调函数作为参数传递?的实战教程也可以访问 https://www.itying.com/category-94-b0.html

2 回复

我认为你无法直接做到这一点。Java 和 Go 拥有不同的运行时环境,它们的内存布局也不同。Java 的垃圾回收器无法回收从 Go 分配的对象,它根本做不到。它们只是采用了不同的方式来进行垃圾回收。Java 中的字符串也与 Go 中的字符串不同。Java 中的函数也与 Go 中的函数不同。它们的代码表示形式也不同。

但是,它们确实都提供了对 C 语言的 FFI。Go 可以使用 CGo 调用 C 代码(需要一些调整),Java 也可以使用 Java JNI 调用 C 代码(同样需要一些调整)。你或许可以从 Java 调用 C,然后从那个 C 代码中调用 Go。但这可能会非常棘手,难以调试,并且难以维护。

更多关于Golang中能否将Java的回调函数作为参数传递?的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


在Golang中通过gomobile向Java传递回调函数是有限制的。gomobile目前不支持直接将函数类型作为参数在Go和Java之间传递。不过,可以通过接口的方式实现类似功能。

以下是可行的解决方案:

// 定义回调接口
type Callback interface {
    OnMessage(msg string)
}

// 全局变量存储回调实例
var callbackInstance Callback

// 导出函数设置回调
func SetCallback(cb Callback) {
    callbackInstance = cb
}

// 触发回调的示例函数
func TriggerCallback() {
    if callbackInstance != nil {
        callbackInstance.OnMessage("Hello from Go")
    }
}

在Java端需要实现对应的接口:

public class MyCallback implements Callback {
    @Override
    public void OnMessage(String msg) {
        // 处理来自Go的消息
        Log.d("GoCallback", "Received: " + msg);
    }
}

// 使用示例
MyCallback callback = new MyCallback();
GoModule.SetCallback(callback);

如果需要从Go主动调用Java,可以这样实现:

package mymodule

import "sync"

type Callback interface {
    OnEvent(data string)
}

var (
    callbackMu sync.RWMutex
    currentCallback Callback
)

//export SetCallback
func SetCallback(cb Callback) {
    callbackMu.Lock()
    defer callbackMu.Unlock()
    currentCallback = cb
}

//export SendData
func SendData(data string) {
    callbackMu.RLock()
    defer callbackMu.RUnlock()
    if currentCallback != nil {
        currentCallback.OnEvent(data)
    }
}

对于需要传递多个回调的情况,可以使用接口组合:

type DataCallbacks interface {
    OnSuccess(data string)
    OnError(err string)
    OnProgress(percent int)
}

var dataCallbacks DataCallbacks

func SetDataCallbacks(cb DataCallbacks) {
    dataCallbacks = cb
}

func ProcessData() {
    if dataCallbacks != nil {
        dataCallbacks.OnProgress(50)
        // 处理逻辑...
        dataCallbacks.OnSuccess("处理完成")
    }
}

这种方法利用了gomobile对接口类型的支持,通过定义接口并在Java端实现该接口,实现了Go到Java的回调机制。注意需要确保接口方法的首字母大写以便导出。

回到顶部