如何从Java进行同步\异步本机调用

时间:2014-09-19 05:16:13

标签: java android java-native-interface synchronous jniwrapper

我正在为Android开发一款国际象棋游戏,并计划使用用C ++编写的AI引擎。 所以,我必须从Java到C ++进行本机方法调用。来源看起来像这样:

Computer.java

class Computer{
  public native String dumpMethod();
  static{
   System.loadLibrary("mylib");
}

public static String makeMove(){
   return dumpMethod();
}

和c ++文件:mylib.cpp

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

#ifdef __cplusplus
extern "C" {
#endif
JNIEXPORT void JNICALL Java_Computer_dumpMethod(JNIEnv *, jobject);
JNIEXPORT void JNICALL Java_Computer_dumpMethod(JNIEnv *env, jobject obj){
  ...
  Engine * engine = new Engine();
  engine->setLevel(10);
  std::string rsult = engine->generateMove();
  ...
  //return result
  ...
}

#ifdef __cplusplus
}
#endif

当我从主活动中调用Computer.makeMove()时,程序在logcat窗口中没有任何错误信息而崩溃。我不知道这个问题,但似乎因为generateMove()执行。

当级别设置为10时,generateMove()调用需要很长时间(最多15秒)才能完成。我认为Android活动不能等到它完成并且它已经崩溃了。

如果级别设置为1,则Everthing效果很好,这意味着generateMove()可以完成并立即返回执行结果。

我想我需要以同步方式拨打电话,但我不知道。 有没有办法以同步/异步方式进行本机调用?

1 个答案:

答案 0 :(得分:0)

我猜你正在调用JNI Native方法:来自主线程的dumpMethod, 在执行本机代码期间阻止主线程。 因此,当你升级到10级时,花费在1级以上的时间超过几毫秒/秒,你就得到了ANR - 应用程序无响应异常。

尝试生成一个新线程并从后台线程调用本机方法,然后当您想要更新UI时,将消息发送到主线程消息队列。