В приложении Android NDK, использующем android-ndk-r9, отсутствуют файлы *.so в окончательном apk, а собственный метод не найден

Обновление: мне удалось упаковать файлы *.so с окончательным apk, просто добавив это в build.gradle:

    tasks.withType(com.android.build.gradle.tasks.PackageApplication) {
        pkgTask -> pkgTask.jniDir new File(projectDir, 'src/main/libs')
    }

Но теперь нативная функция не вызывается.

код native.c

    #include <jni.h>
    #include <string.h>
    #include <android/log.h>

    JNIEXPORT jstring JNICALL Java_com_myndkapp_mybullet_MainActivity_helloLog(JNIEnv * env, jobject this) {
        __android_log_print(ANDROID_LOG_DEBUG, DEBUG_TAG, "NDK:LC: [%s]", "Check string you received in the Activity");
        return (*env)->NewStringUTF(env, "Hello from Native code :)");
    }

Фрагмент из MainActivity.java :

    .
    ..
    static {
            System.loadLibrary("myfndk");
        }
    private native String helloLog();
    .
    ..

Некоторые следы журнала ADB находятся здесь:

    11-18 16:53:43.261    3469-3469/? D/PackageAddedReceiver﹕ package added com.myndkapp.mybullet
    11-18 16:53:43.856    2963-3214/? V/SmartFaceService - 3rd party pause﹕ onReceive [android.intent.action.ACTIVITY_STATE/com.myndkapp.mybullet/create]
    11-18 16:53:43.886    2823-2823/? D/dalvikvm﹕ Trying to load lib /data/app-lib/com.myndkapp.mybullet-1/libmyfndk.so 0x42a99270
    11-18 16:53:43.886    2823-2823/? D/dalvikvm﹕ Added shared lib /data/app-lib/com.myndkapp.mybullet-1/libmyfndk.so 0x42a99270
    11-18 16:53:43.886    2823-2823/? D/dalvikvm﹕ No JNI_OnLoad found in /data/app-lib/com.myndkapp.mybullet-1/libmyfndk.so 0x42a99270, skipping init
    11-18 16:53:50.596    2823-2823/? W/dalvikvm﹕ No implementation found for native Lcom/myndkapp/mybullet/MainActivity;.helloLog:()Ljava/lang/String;
    11-18 16:53:50.606    2823-2823/? E/AndroidRuntime﹕ FATAL EXCEPTION: main
java.lang.UnsatisfiedLinkError: Native method not found:         com.myndkapp.mybullet.MainActivity.helloLog:()Ljava/lang/String;
        at com.myndkapp.mybullet.MainActivity.helloLog(Native Method)
        at com.myndkapp.mybullet.MainActivity.access$000(MainActivity.java:15)
        at com.myndkapp.mybullet.MainActivity$1.onClick(MainActivity.java:35)
        at android.view.View.performClick(View.java:4475)
        at android.view.View$PerformClick.run(View.java:18786)
        at android.os.Handler.handleCallback(Handler.java:730)
        at android.os.Handler.dispatchMessage(Handler.java:92)
        at android.os.Looper.loop(Looper.java:137)
        at android.app.ActivityThread.main(ActivityThread.java:5419)
        at java.lang.reflect.Method.invokeNative(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:525)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1187)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1003)
        at dalvik.system.NativeStart.main(Native Method)
    11-18 16:53:50.691    2963-3214/? V/SmartFaceService - 3rd party pause﹕ onReceive [android.intent.action.ACTIVITY_STATE/com.myndkapp.mybullet/pause]
    11-18 16:53:50.696    2963-3043/? D/CrashAnrDetector﹕ processName: com.myndkapp.mybullet
    11-18 16:53:50.696    2963-3043/? D/CrashAnrDetector﹕ broadcastEvent : com.myndkapp.mybullet data_app_crash
    11-18 16:54:05.781    2963-3449/? I/ActivityManager﹕ Process com.myndkapp.mybullet (pid 2823) (adj 9) has died.

Я пытаюсь создать приложение Android NDK, используя android-ndk-r9 в Android Studio 0.3.5 132.910074 на Fedora 19 x86_64.

Похоже, что libmyfndk.so не добавлен в окончательный файл apk. Я подтвердил это, просмотрев содержимое файла apk. Когда я запускаю это тестовое приложение на своем Galaxy S4 (Jelly Bean 4.3), оно выдает ошибку.

    11-17 19:03:28.816  26472-26472/com.myndkapp.mybullet E/AndroidRuntime﹕ 
    FATAL EXCEPTION: main
    java.lang.UnsatisfiedLinkError: Couldn't load myfndk from loader 
    dalvik.system.PathClassLoader[dexPath=/data/app/com.myndkapp.mybullet-1.apk,
    libraryPath=/data/app-lib/com.myndkapp.mybullet-1]: findLibrary returned null

Я посмотрел на решения здесь:

1.) https://groups.google.com/forum/#!msg/adt-dev/xj51eCWwhFw/pfhvCoquPysJ

2.) https://groups.google.com/forum/?fromgroups#!searchin/adt-dev/so/adt-dev/nQobKd2Gl_8/Z5yWAvCh4h4J

3.) Android studio, gradle и NDK

3.1) https://stackoverflow.com/a/16790675/1673000 (это сработало для меня)

4.) https://github.com/OnlyInAmerica/Android-JNI-Gradle

5.) Включить библиотеку .so в apk в студии Android

Похоже, ничего из этого не работает.

Это содержимое моего файла build-gradle.

    buildscript {
        repositories {
            mavenCentral()
        }
        dependencies {
            classpath 'com.android.tools.build:gradle:0.6.3'
        }
    }
    apply plugin: 'android'

    repositories {
        mavenCentral()
    }

    android {
        compileSdkVersion 18
        buildToolsVersion '19.0.0'

        defaultConfig {
            minSdkVersion 10
            targetSdkVersion 19
        }
    }

    dependencies {
        compile 'com.android.support:appcompat-v7:+'
    }

Любые подсказки, почему функция Native не вызывается?


person Manmohan Bishnoi    schedule 17.11.2013    source источник
comment
вы загрузили библиотеку во время выполнения с помощью System.load? Ваш файл скопирован в правильную подпапку abi внутри libs?   -  person MLProgrammer-CiM    schedule 18.11.2013
comment
Я загружаю библиотеку в MainActivity вот так static {System.loadLibrary("myfndk");} и libmyfndk.so файл здесь src/main/libs/armeabi/   -  person Manmohan Bishnoi    schedule 18.11.2013
comment
может быть, ваш тестовый образец использует armeabi-v7a?   -  person MLProgrammer-CiM    schedule 18.11.2013
comment
В Android.mk есть эта строка APP_ABI := all, поэтому я думаю, что это не должно быть проблемой.   -  person Manmohan Bishnoi    schedule 18.11.2013
comment
Не гадайте, измените его на armeabi-v7a вручную, пересоберите и убедитесь, что это тот, который есть в вашем приложении. APP_ABI обычно также входит в Application.mk, но не уверен, что он применяется при вызове из Android.mk.   -  person MLProgrammer-CiM    schedule 18.11.2013
comment
Я только что попробовал, пересоберите мою библиотеку, используя ndk-build, пересоберите apk. Все та же ошибка.   -  person Manmohan Bishnoi    schedule 18.11.2013
comment
stackoverflow.com/a/10098466/1266326 подтверждение того, что APP_ABI должен войти в Application.mk   -  person MLProgrammer-CiM    schedule 18.11.2013
comment
Это НЕ проблема ABI, так как в журнале указано, что библиотека найдена и загружена.   -  person Chris Stratton    schedule 18.11.2013
comment
НЕИСПРАВНОЕ ИСКЛЮЧЕНИЕ: main java.lang.UnsatisfiedLinkError: Не удалось загрузить myfndk из загрузчика, о котором идет речь, поэтому я предположил, что это так.   -  person MLProgrammer-CiM    schedule 18.11.2013
comment
У него есть автоматически сгенерированный заголовочный файл?   -  person MLProgrammer-CiM    schedule 18.11.2013
comment
@EfEs Это ошибка Native method not found, от которой я не могу избавиться.   -  person Manmohan Bishnoi    schedule 18.11.2013
comment
Вы использовали javah для создания правильного заголовка?   -  person MLProgrammer-CiM    schedule 18.11.2013
comment
Нет, я этим не пользовался.   -  person Manmohan Bishnoi    schedule 18.11.2013
comment
Но у вас есть правильный заголовок?   -  person MLProgrammer-CiM    schedule 18.11.2013
comment
У меня просто есть файлы «Android.mk», «Application.mk» и «native.c» в каталоге «jni». Я следовал этому руководству mobile.tutsplus.com/tutorials/android/ndk-tutorial   -  person Manmohan Bishnoi    schedule 18.11.2013
comment
Было бы полезно извлечь .so из .apk с помощью инструментов zip и использовать на нем ndk objdump, чтобы убедиться, что функция действительно находится внутри. Иногда изменения не распространяются, и когда вы тестируете текущий код, вы на самом деле тестируете устаревшие артефакты сборки. Кроме того, для полноты опубликуйте объявление java нативного метода.   -  person Chris Stratton    schedule 18.11.2013
comment
@ChrisStratton вот objdump для libmyfndk.so: pastebin.com/GPt5QPDy, также добавлено объявление java функции в оригинальный вопрос.   -  person Manmohan Bishnoi    schedule 18.11.2013
comment
Если это все, у вас фактически пустая библиотека или по крайней мере одна без каких-либо полезных динамических символов. Правильно ли вы используете систему сборки nkd? Если вы, например, соберете пример hello-jni с помощью ndk-build, вы найдете функции Java_, перечисленные в objdump этого файла .so.   -  person Chris Stratton    schedule 18.11.2013
comment
Вот как я его создаю pastebin.com/dCGevjif , я выполняю это в каталоге проекта, и библиотеки генерируются, как показано.   -  person Manmohan Bishnoi    schedule 18.11.2013
comment
Тем не менее, может показаться, что с вашей сборкой что-то не так. Находит ли grep любое вхождение имени функции Java_ в файл библиотеки? В промежуточных объектах? Попробуйте собрать hello-jni строго по инструкции для сравнения.   -  person Chris Stratton    schedule 18.11.2013
comment
Я создал hello-jni, затем obj-dump выдает это pastebin.com/XaNgi2Xy, поэтому мой NDK настроен правильно.   -  person Manmohan Bishnoi    schedule 18.11.2013
comment
Что ж, теперь вам просто нужно понять, в чем разница — почему в одной библиотеке вы получаете функцию, а в другой — нет. Одна вещь, которая может помочь, — это преобразовать копию проекта hello-jni в то, что вам нужно, шаг за шагом, видя, где он ломается.   -  person Chris Stratton    schedule 18.11.2013
comment
Спасибо, я проведу вскрытие моего проекта и посмотрю, в чем причина. Большое спасибо за направление в правильном направлении.   -  person Manmohan Bishnoi    schedule 18.11.2013


Ответы (1)


Это не размещение кода native.c в libmyfndk.so из-за отсутствия '=' в моем Android.mk в этой строке:

LOCAL_SRC_FILES : native.c

Изменение вышеуказанной строки на LOCAL_SRC_FILES := native.c решило эту проблему.

person Manmohan Bishnoi    schedule 19.11.2013