Собственные функции генерируют UnsatisfiedLinkError в пользовательском представлении, несмотря на работу в основной деятельности - PullRequest
0 голосов
/ 21 декабря 2010

По какой-то причине я могу вызывать собственные функции только из основного занятия, а не из созданных мной пользовательских представлений. Вот пример файла (я следовал учебнику, но переименовал классы 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 Ответ

3 голосов
/ 22 декабря 2010

Ваша проблема в том, что вы пытаетесь вызвать нативную функцию из класса, которому она не принадлежит.

Вы определили следующую функцию JNI в вашем файле c:

jstring Java_com_example_native_NativeTestActivity_getNewString()

Это говорит о том, что встроенная функция при загрузке будет привязана к методу, объявленному как собственный в классе NativeTestActivity .Поэтому, когда вы пытаетесь вызвать его из вашего 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 код:

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