开发者

Native functions throw UnsatisfiedLinkError in custom view, despite working in main activity

For some reason I can only call native functions from my main activity and not any custom views that I've created. Here is an example file (I followed a tutorial, but renamed the classes http://mindtherobot.com/blog/452/android-beginners-ndk-setup-step-by-step/)

See the usage of the native function "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
    {
     开发者_如何学Python   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();
    }
}

How can I call native functions in my custom views?

I've built the application as an Android 2.2 app. I'm running the application on my HTC Desire. I have the latest SDK (9) and latest NDK (r5).


Your problem is that you are trying to call the native function from a class where it dont belongs to.

You defined the following JNI function in your c file:

jstring Java_com_example_native_NativeTestActivity_getNewString()

This states that the native function when loaded will bind with the method declared as native in NativeTestActivity class. So when you try to call it from your View class it doesn't find any function to bind to.

In that case it will look for the following function (which of course does not exist in your .so):

jstring Java_com_example_native_BitmapView_getNewString()

If you still want to be able to call the same function from different classes you can declare it in a container class that can be accessed from any class you want.

eg:

java code:

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!");
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜