简而言之:显然,必须在发出loadLibrary调用的同一个类中声明本机方法。如果在静态内部类中声明本机方法,则绑定失败。
工作示例:
imageView.setImageDrawable(getResource().getDrawable(R.drawable.animation);
AnimationDrawable animation = (AnimationDrawable)imageView.getDrawable();
animation.start();
示例失败:
public class TestNative
{
public TestNative()
{
System.loadLibrary( "mylibrary");
}
private native int nativeMethod();
public void doit()
{
new NativeWrap().callNative();
}
class NativeWrap
{
int callNative()
{
return nativeMethod(); // <<<< works
}
}
}
BTW:loadLibrary在两个示例中都有效。
我没有找到关于这个主题的任何提示。我发现的所有JNI示例都在声明本机方法的同一个类中加载库。有人可以对这些东西发光吗?
答案 0 :(得分:1)
它完美无缺。放置库的位置并不重要。这里重要的是方法的名称。如果您生成方法签名,然后将方法移动到其他位置,则无法运行。
看看这里:
package recipeNo001;
public class HelloWorld {
static {
System.loadLibrary("HelloWorld");
}
private native void displayMessage();
static class NativeWrapper {
void callNative() {
displayMessageInner();
}
private native void displayMessageInner();
}
public static void main(String[] args) {
new HelloWorld().displayMessage();
new NativeWrapper().callNative();
}
}
但是你必须确保在库中提供正确的名称。注意两者之间的区别:
JNIEXPORT void JNICALL Java_recipeNo001_HelloWorld_displayMessage
(JNIEnv *env, jclass obj)
JNIEXPORT void JNICALL Java_recipeNo001_HelloWorld_00024NativeWrapper_displayMessageInner
(JNIEnv *env, jobject obj)
当然,它有效。
Hello world from enclosing class!
Hello world from wrapper!
而且,在您的情况下,您还有另一个问题。如果您不在静态块中加载库,则必须确保在调用本机方法之前实例化该类的至少一个对象。
在示例代码中看看这里:
https://github.com/mkowsiak/jnicookbook/tree/master/recipeNo034