尽管在主要活动中工作,本机函数在自定义视图中抛出UnsatisfiedLinkError

时间:2010-12-21 12:09:18

标签: java c++ android android-ndk android-ndk-r5

出于某种原因,我只能从我的主要活动调用本机函数,而不能调用我创建的任何自定义视图。这是一个示例文件(我遵循了教程,但重命名了类http://mindtherobot.com/blog/452/android-beginners-ndk-setup-step-by-step/

查看本机函数“getNewString”的用法。

package com.example.native;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.os.Bundle;
import android.view.View;

public class NativeTestActivity extends Activity
{   
    static
    {
        System.loadLibrary("nativeTest");
    }

    private native String getNewString();

    @Override public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);        
        this.setContentView(new BitmapView(this));

        String hello = getNewString(); // This line works fine
        new AlertDialog.Builder(this).setMessage(hello).show();
    }
}

class BitmapView extends View
{
    static
    {
        System.loadLibrary("nativeTest");
    }

    private native String getNewString();

    public BitmapView(Context context)
    {
        super(context);

        String hello = getNewString(); // This line throws the UnsatisfiedLinkError
        new AlertDialog.Builder(this.getContext()).setMessage(hello).show();
    }
}

如何在自定义视图中调用本机函数?

我已将该应用程序构建为Android 2.2应用程序。我在HTC Desire上运行应用程序。我有最新的SDK(9)和最新的NDK(r5)。

1 个答案:

答案 0 :(得分:3)

你的问题是你试图从一个它不属于的类中调用本机函数。

您在c文件中定义了以下JNI函数:

jstring Java_com_example_native_NativeTestActivity_getNewString()

这表明加载时的本机函数将与 NativeTestActivity 类中声明为native的方法绑定。因此,当您尝试从 View 类调用它时,它找不到任何要绑定的函数。

在这种情况下,它将寻找以下功能(当然,你的.so中不存在):

jstring Java_com_example_native_BitmapView_getNewString()

如果你仍然希望能够从不同的类中调用相同的函数,你可以在容器类中声明它,可以从任何你想要的类访问它。

例如:

java代码

package com.example.native;
public class NativeHelper {
     public native String getNewString();
     static
     {
         System.loadLibrary("nativeTest");
     }
}

c code:

jstring Java_com_example_native_NativeHelper_getNewString(JNIEnv* env, jobject javaThis)
{
     return (*env)->NewStringUTF(env, "Hello from native code!");
}