我可以使用 jni 从 cpp 调用可组合的 kotlin 函数(jetpack compose)吗

问题描述 投票:0回答:1

我知道我们可以使用 JNI 在 cpp 中调用普通的 Kotlin 方法,方法是使用 (env)->GetMethodID(class, Methodname, signatures) 和 (env)->CallVoidMethod(object, methodID, parameters)

但是在使用 jetpack compose 时,我无法对可组合的 kotlin 方法执行相同的操作。 (env)->GetMethodID 在这种情况下返回 null。

我收到错误:

java.lang.NoSuchMethodError: 没有非静态方法“Lcom/example/jetpackcompose/MainActivity;.MessageCard(Ljava/lang/String;Ljava/lang/String;)V”

我还尝试从不可组合方法调用可组合方法,并从 jni 调用不可组合方法,但这也是不可能的,因为可组合方法只能从另一个可组合方法调用。

有没有办法从 jni 调用可组合的 kotlin 方法?

MainActivity.kt

class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContent {
        var str:String = stringFromJNI()
        MessageCardCpp()
    }
}

@Composable
fun MessageCard(author: String, body: String) {
    Row() {

        Image(painter = painterResource(R.drawable.sampleimage),
            contentDescription = "Sample Image",
            modifier = Modifier
                .size(80.dp)
                .clip(CircleShape)
        )

        Spacer(modifier = Modifier.width(8.dp))

        Column() {
            Text(author, fontSize = 30.sp)
            Spacer(modifier = Modifier.width(4.dp))
            Text(body, fontSize = 30.sp)
        }
    }
}

external fun stringFromJNI(): String
external fun MessageCardCpp()

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

native-lib.cpp

extern "C" JNIEXPORT void JNICALL
Java_com_example_jetpackcompose_MainActivity_MessageCardCpp(JNIEnv *env, jobject thiz) {

jclass MainActivity = (env)->FindClass("com/example/jetpackcompose/MainActivity");

if(MainActivity == nullptr) {

    __android_log_print(ANDROID_LOG_DEBUG, "Demo", "%s", "GetClass returns Null");
    return;
}

jmethodID MessageCard = (env)->GetMethodID(MainActivity, "MessageCard","(Ljava/lang/String;Ljava/lang/String;)V");

if(MessageCard == nullptr) {

    __android_log_print(ANDROID_LOG_DEBUG, "Demo", "%s", "GetMethodID returns Null");
    return;
}

(env)->CallVoidMethod(thiz, MessageCard, env->NewStringUTF("Android JetPack"), env->NewStringUTF("Hello Cpp"));
}
android kotlin java-native-interface android-jetpack-compose
1个回答
1
投票

恐怕你的问题是不可能的。 @Composable 注释由 Android Kotlin 插件在编译时 简单地通过检查所有方法/函数调用来处理。 生成的代码不再包含 @Composable 调用,而是对表示应用程序布局以及如何呈现它的图形的引用。

相比之下,JNI代码只能在运行时执行,所以调用@Composable方法已经来不及了。

© www.soinside.com 2019 - 2024. All rights reserved.