我知道我们可以使用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;/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"));
}
1条答案
按热度按时间a6b3iqyw1#
我恐怕你的问题是不可能的。AndroidKotlin插件在 * 编译时 * 通过检查所有方法/函数调用来处理@Composable注解。生成的代码不再包含@Composable调用,而是对表示应用程序布局以及如何呈现它的图形的引用。
相比之下,JNI代码只能在运行时执行,因此调用@Composable方法为时已晚。