看NDK自带的例子及书籍,看起来挺容易的,等自己动手去实现时,发现会遇到这样或那样的问题。在解决这些问题过程会收获的,建议自己重新创建项目来实现。
下面内容是在NDK环境配置好的情况下执行的。
本地库的实现:
//hello.c
#include <jni.h>//使用JNI调用c/c++程序就必须包含这个头文件
void Java_gdream_project_MainActivity_nativeMethod(JNIEnv* env,jobject this )
{
jclass jNativesCls; //java类
jmethodID mid; //java方法ID
jNativesCls = (*env)->FindClass(env, "gdream/project/MainActivity");//获取MainActivity这个类
if(jNativesCls)
{ //通过类,方法,参数列表,返回类型获取方法ID
mid = (*env)->GetStaticMethodID(env, jNativesCls
, "javaMethod"
, "(I)V");
}
if (mid)
{
//调用java层的方法
(*env)->CallStaticVoidMethod(env, jNativesCls, mid,10);
}
}
值得注意的是:GetStaticMethodID方法最后那个参数的格式为(ARGUMENTS)RETURN_TYPE,其中“参数”可以编码为
I = Integer(整型)
B = Byte(字节)
S = Short(短整型)
C = Char(字符)
LJava_Class; = Java类,包围在L和;之间
如果是空类型的话,得这样写"()V",否则会提示找不到方法的。
package gdream.project;
import android.app.Activity;
import android.os.Bundle;
public class MainActivity extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
// System.out.println("1xxxx!");
nativeMethod();//调用c层方法
setContentView(R.layout.main);
}
public native void nativeMethod();
private static void javaMethod(int i )
{
System.out.println("hello world!");
}
static
{
System.loadLibrary("javaAndC");
}
}
为什么要写成Java_gdream_project_MainActivity_nativeMethod这样呢。
这个跟java的方法最终编译成bin有关系,编译器在编译java的方法时,会在方法前面加上Java,包名,类名,所以MainActivity这个类里面声明的方法nativeMethod会被替换成
Java_gdream_project_MainActivity_nativeMethod。但是理论上来说,在链接的时候会提示找不到该方法,因为这个方法的定义是在共享库里,而共享库是在运行时才加载进去的。具体是怎样子的,有待进一步了解。
这个运行的结果是:在LogCat上面显示 hello world! 这说明成功的解决了java层与c层方法互调的问题。当然这只是简单的,也许后面
参考资料:1,精通Android游戏编程,[美]Vladimir Silva
2,NDK自带例子