【问题标题】:Callback from c++ to Kotlin using JNI : Android使用 JNI 从 c++ 回调到 Kotlin:Android
【发布时间】:2021-03-10 15:26:49
【问题描述】:

有没有办法以固定的时间间隔直接从 c++ 调用 Kotlin 函数? 我是 JNI 新手,与此相关的堆栈溢出中的大多数问题都涉及 JNIEnv obj,但要访问此对象,我必须在 MainActivity 中创建一个外部函数并在 Kotlin 世界中触发它。

这是目标的虚拟代码。

主要活动

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        performComputation();
    }

    external fun stringFromJNI(): String // The default method that retrieves a string

    external fun performComputation(); 


    fun updateUI(someValue: Int){
    // Code to Update UI. This method must be called from C++ in regular intervals
   
    } 

    companion object {
        // Used to load the 'native-lib' library on application startup.
        init {
            System.loadLibrary("native-lib")
        }
    }
}

Native-lib.cpp

#include <jni.h>
#include <string>
#include "staticClass.h"

extern "C" JNIEXPORT void JNICALL
Java_com_twrotu_testapplication_MainActivity_performComputation(
        JNIEnv* env,
        jobject) {
    accumulate();
}

StaticClass.h

#ifndef TEST_APPLICATION_STATICCLASS_H
#define TEST_APPLICATION_STATICCLASS_H

int num1 = 5;
int num2 = 10;

void accumulate(){
    while (num1 <= 100){
        num1 += num2;
        if (num1%2 == 0 ){
            // Trigger a Java Method and Update UI whenever num1 is even

        }
    }
}

#endif //TEST_APPLICATION_STATICCLASS_H

理想情况下,每当来自 Static.h 的 Num1 甚至在累积()函数中时,我都能够触发 Kotlin 方法。这可能吗 ?如果是,请分享有用的资源,并就我必须如何解决这个问题给我一些见解。我可以使用 google 找到很多资源,但我无法正确理解。

TIA。

【问题讨论】:

  • 保存您在JNI_OnLoad 中收到的JavaVM*,以便您可以随时使用它来获取JNIEnv*。至于MainActivity 实例,您已经拥有它,因为performComputation 将它作为它的参数之一接收。因此,创建一个对其的全局引用并将其保存在某处,以便accumulate 可以访问它。
  • 您可能需要考虑使用 JavaCPP 之类的工具来抽象出所有这些细节:github.com/bytedeco/javacpp

标签: android c++ kotlin java-native-interface


【解决方案1】:

您可以使用继承和从 C++ 类到 Kotlin 类以及 C++ 中的指针来调用实习生调用您的函数的虚函数

著名的 SWIG 工具提供了这样的功能,我在 github 中有一个示例 Kotlin SWIG JNI Inheritance and Callback

它的作用是,它调用如下的虚函数

void jniexample::Caller::call() { 
    if (_callback) { 
        _callback->run();
    } 
}

run() 是如下的虚函数

namespace jniexample {
    class Callback {
        public:
        virtual void JNIEXAMPLE_EXPORT_FUNC run();

在调用 SWIG 命令时,我们传递了 -directors,它会自动存根回调

在 Kotlin 代码中

var callback = KotlinCallback()
var caller = Caller()
caller.setCallback(callback)
caller.call()
caller.delCallback()

这里caller.call() 将从C++ 指针调用KotlinCallback

【讨论】:

    猜你喜欢
    • 2018-03-19
    • 2019-04-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-28
    相关资源
    最近更新 更多