1. 加载库的函数
java.lang.UnsatisfiedLinkError: Library foo not found
是 System.loadLibrary("jni");
不是System.load("jni");
2. 库的名字
libjni.so -> jni
3. jni的函数名
完全按照:java_pacakege_class_method 形式来命名。
java_com_example_jni_MainActivity_GetString();
//java
package com.example.jni;
import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.TextView;
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
TextView tv = new TextView(this);
tv.setText(GetString());
setContentView(tv);
}
public native String GetString();
static {
System.loadLibrary("jni");
}
}
//c
#include
#include
#ifdef __cplusplus
extern "C" {
#endif
//java_pacakege_class_method
jstring
Java_com_example_jni_MainActivity_GetString( JNIEnv* env,
jobject thiz )
{
return env->NewStringUTF( "Hello from JNI ! Compiled with ABI " );
}
#ifdef __cplusplus
}
#endif
一些问题与解决方法:
问题一:Android NDK: WARNING: APP_PLATFORM android-14 is larger than android:minSdkVersion 8 in ./AndroidManifest.xml (这个是NDK工具的一个BUG,若build Target大于minSdkVersion,则会报这个错误,导致无法运行)
解决方法:
android-ndk-r8e/build/core/add-application.mk第128行把__ndk_warning改为__ndk_info;然后重新build一次项目即可消除错误。
原文:
this problem may be safely fixed by changing this line in add-application.mk from __ndk_warning to __ndk_info链接:
问题二:使用c++来编写本地库,会有一些兼容问题。
(1)直接黏贴HelloJni的stringFromJNI函数过来测试,提示Method 'NewStringUTF' could not be resolved解决方法:
改为:将(*env)->NewStringUTF(env, "Hello from JNI !")改为return env->NewStringUTF("Hello from JNI !")即可
原因是:
NDK plugin默认为我们生成的是cpp文件,而C与C++调用函数的参数不一致,因此找不到函数,具体参考jni.h中的定义。cpp文件中形如(*env)->Method(env, XXX)改成env->Method(XXX)即可。
(2)运行c++生成的.so库,若报以下错误:(既找不到函数)
No implementation found for native Lcom/dgut/android/MainActivity;.stringFromJNI ()Ljava/lang/String;
java.lang.UnsatisfiedLinkError: stringFromJNI
at com.dgut.android.MainActivity.stringFromJNI(Native Method)
#ifdef __cplusplus
extern "C" {
#endif
//
#ifdef __cplusplus
}
#endif