Android NDK - Kesalahan Pembuatan Gradle

Saya telah berhasil mengkompilasi perpustakaan SoundTouch dan menyalin file yang dihasilkan ke folder libs proyek saya.

perpustakaan

di dalam masing-masing folder ini ada file libsoundtouch.so.

di folder jni proyek saya, saya memiliki file berikut:

  • Android.mk
  • Aplikasi.mk
  • soundtouch-jni.cpp

Android.mk saya terlihat seperti ini:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

# *** Remember: Change -O0 into -O2 in add-applications.mk ***

LOCAL_MODULE    := soundtouch
LOCAL_SRC_FILES := soundtouch-jni.cpp ../../SoundTouch/AAFilter.cpp  ../../SoundTouch/FIFOSampleBuffer.cpp \
                ../../SoundTouch/FIRFilter.cpp ../../SoundTouch/cpu_detect_x86.cpp \
                ../../SoundTouch/sse_optimized.cpp ../../SoundStretch/WavFile.cpp \
                ../../SoundTouch/RateTransposer.cpp ../../SoundTouch/SoundTouch.cpp \
                ../../SoundTouch/InterpolateCubic.cpp ../../SoundTouch/InterpolateLinear.cpp \
                ../../SoundTouch/InterpolateShannon.cpp ../../SoundTouch/TDStretch.cpp \
                ../../SoundTouch/BPMDetect.cpp ../../SoundTouch/PeakFinder.cpp 

# for native audio
LOCAL_SHARED_LIBRARIES += -lgcc 
# --whole-archive -lgcc 
# for logging
LOCAL_LDLIBS    += -llog
# for native asset manager
#LOCAL_LDLIBS    += -landroid

# Custom Flags: 
# -fvisibility=hidden : don't export all symbols
LOCAL_CFLAGS += -fvisibility=hidden -I ../../../include -fdata-sections -ffunction-sections

# OpenMP mode : enable these flags to enable using OpenMP for parallel computation 
#LOCAL_CFLAGS += -fopenmp
#LOCAL_LDFLAGS += -fopenmp


# Use ARM instruction set instead of Thumb for improved calculation performance in ARM CPUs 
LOCAL_ARM_MODE := arm

include $(BUILD_SHARED_LIBRARY)

dan ini file module build.gradle saya:

apply plugin: 'com.android.application'

android {
    signingConfigs {
        dev_key {
            keyAlias '#########'
            keyPassword '########'
            storeFile file('/Users/daniele/Desktop/Chords/########')
            storePassword '#######'
        }
    }
    compileSdkVersion 26
    buildToolsVersion "26.0.1"
    defaultConfig {
        applicationId "com.dancam.chords"
        minSdkVersion 21
        targetSdkVersion 26
        versionCode 16
        versionName "2.1"
        signingConfig ##########
        multiDexEnabled true
    }
    buildTypes {
        release {
            shrinkResources true
            minifyEnabled true
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
    productFlavors {
    }

    dataBinding {
        enabled = true
    }
}

dependencies {
    compile fileTree(include: ['*.jar'], dir: 'libs')
    androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
        exclude group: 'com.android.support', module: 'support-annotations'
    })

Saya mengimpor fungsi asli:

public final class SoundTouch {
    public native final static String getVersionString();

// Load the native library upon startup
static
{
    System.loadLibrary("soundtouch");
}
}

Ini file soundtouch-jni.cpp saya:

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

using namespace std;

#include "../../../include/SoundTouch.h"
#include "../source/SoundStretch/WavFile.h"

#define LOGV(...)   __android_log_print((int)ANDROID_LOG_INFO, "SOUNDTOUCH", __VA_ARGS__)
//#define LOGV(...)


// String for keeping possible c++ exception error messages. Notice that this isn't
// thread-safe but it's expected that exceptions are special situations that won't
// occur in several threads in parallel.
static string _errMsg = "";


#define DLL_PUBLIC __attribute__ ((visibility ("default")))
#define BUFF_SIZE 4096


using namespace soundtouch;


// Set error message to return
static void _setErrmsg(const char *msg)
{
    _errMsg = msg;
}


#ifdef _OPENMP

#include <pthread.h>
extern pthread_key_t gomp_tls_key;
static void * _p_gomp_tls = NULL;

/// Function to initialize threading for OpenMP.
///
/// This is a workaround for bug in Android NDK v10 regarding OpenMP: OpenMP works only if
/// called from the Android App main thread because in the main thread the gomp_tls storage is
/// properly set, however, Android does not properly initialize gomp_tls storage for other threads.
/// Thus if OpenMP routines are invoked from some other thread than the main thread,
/// the OpenMP routine will crash the application due to NULL pointer access on uninitialized storage.
///
/// This workaround stores the gomp_tls storage from main thread, and copies to other threads.
/// In order this to work, the Application main thread needws to call at least "getVersionString"
/// routine.
static int _init_threading(bool warn)
{
    void *ptr = pthread_getspecific(gomp_tls_key);
    LOGV("JNI thread-specific TLS storage %ld", (long)ptr);
    if (ptr == NULL)
    {
        LOGV("JNI set missing TLS storage to %ld", (long)_p_gomp_tls);
        pthread_setspecific(gomp_tls_key, _p_gomp_tls);
    }
    else
    {
        LOGV("JNI store this TLS storage");
        _p_gomp_tls = ptr;
    }
    // Where critical, show warning if storage still not properly initialized
    if ((warn) && (_p_gomp_tls == NULL))
    {
        _setErrmsg("Error - OpenMP threading not properly initialized: Call SoundTouch.getVersionString() from the App main thread!");
        return -1;
    }
    return 0;
}

#else
static int _init_threading(bool warn)
{
    // do nothing if not OpenMP build
    return 0;
}
#endif


// Processes the sound file
static void _processFile(SoundTouch *pSoundTouch, const char *inFileName, const char *outFileName)
{
    int nSamples;
    int nChannels;
    int buffSizeSamples;
    SAMPLETYPE sampleBuffer[BUFF_SIZE];

    // open input file
    WavInFile inFile(inFileName);
    int sampleRate = inFile.getSampleRate();
    int bits = inFile.getNumBits();
    nChannels = inFile.getNumChannels();

    // create output file
    WavOutFile outFile(outFileName, sampleRate, bits, nChannels);

    pSoundTouch->setSampleRate(sampleRate);
    pSoundTouch->setChannels(nChannels);

    assert(nChannels > 0);
    buffSizeSamples = BUFF_SIZE / nChannels;

    // Process samples read from the input file
    while (inFile.eof() == 0)
    {
        int num;

        // Read a chunk of samples from the input file
        num = inFile.read(sampleBuffer, BUFF_SIZE);
        nSamples = num / nChannels;

        // Feed the samples into SoundTouch processor
        pSoundTouch->putSamples(sampleBuffer, nSamples);

        // Read ready samples from SoundTouch processor & write them output file.
        // NOTES:
        // - 'receiveSamples' doesn't necessarily return any samples at all
        //   during some rounds!
        // - On the other hand, during some round 'receiveSamples' may have more
        //   ready samples than would fit into 'sampleBuffer', and for this reason
        //   the 'receiveSamples' call is iterated for as many times as it
        //   outputs samples.
        do
        {
            nSamples = pSoundTouch->receiveSamples(sampleBuffer, buffSizeSamples);
            outFile.write(sampleBuffer, nSamples * nChannels);
        } while (nSamples != 0);
    }

    // Now the input file is processed, yet 'flush' few last samples that are
    // hiding in the SoundTouch's internal processing pipeline.
    pSoundTouch->flush();
    do
    {
        nSamples = pSoundTouch->receiveSamples(sampleBuffer, buffSizeSamples);
        outFile.write(sampleBuffer, nSamples * nChannels);
    } while (nSamples != 0);
}



extern "C" DLL_PUBLIC jstring Java_net_surina_soundtouch_SoundTouch_getVersionString(JNIEnv *env, jobject thiz)
{
    const char *verStr;

    LOGV("JNI call SoundTouch.getVersionString");

    // Call example SoundTouch routine
    verStr = SoundTouch::getVersionString();

    /// gomp_tls storage bug workaround - see comments in _init_threading() function!
    _init_threading(false);

    int threads = 0;
    #pragma omp parallel
    {
        #pragma omp atomic
        threads ++;
    }
    LOGV("JNI thread count %d", threads);

    // return version as string
    return env->NewStringUTF(verStr);
}



extern "C" DLL_PUBLIC jlong Java_net_surina_soundtouch_SoundTouch_newInstance(JNIEnv *env, jobject thiz)
{
    return (jlong)(new SoundTouch());
}


extern "C" DLL_PUBLIC void Java_net_surina_soundtouch_SoundTouch_deleteInstance(JNIEnv *env, jobject thiz, jlong handle)
{
    SoundTouch *ptr = (SoundTouch*)handle;
    delete ptr;
}


extern "C" DLL_PUBLIC void Java_net_surina_soundtouch_SoundTouch_setTempo(JNIEnv *env, jobject thiz, jlong handle, jfloat tempo)
{
    SoundTouch *ptr = (SoundTouch*)handle;
    ptr->setTempo(tempo);
}


extern "C" DLL_PUBLIC void Java_net_surina_soundtouch_SoundTouch_setPitchSemiTones(JNIEnv *env, jobject thiz, jlong handle, jfloat pitch)
{
    SoundTouch *ptr = (SoundTouch*)handle;
    ptr->setPitchSemiTones(pitch);
}


extern "C" DLL_PUBLIC void Java_net_surina_soundtouch_SoundTouch_setSpeed(JNIEnv *env, jobject thiz, jlong handle, jfloat speed)
{
    SoundTouch *ptr = (SoundTouch*)handle;
    ptr->setRate(speed);
}


extern "C" DLL_PUBLIC jstring Java_net_surina_soundtouch_SoundTouch_getErrorString(JNIEnv *env, jobject thiz)
{
    jstring result = env->NewStringUTF(_errMsg.c_str());
    _errMsg.clear();

    return result;
}


extern "C" DLL_PUBLIC int Java_net_surina_soundtouch_SoundTouch_processFile(JNIEnv *env, jobject thiz, jlong handle, jstring jinputFile, jstring joutputFile)
{
    SoundTouch *ptr = (SoundTouch*)handle;

    const char *inputFile = env->GetStringUTFChars(jinputFile, 0);
    const char *outputFile = env->GetStringUTFChars(joutputFile, 0);

    LOGV("JNI process file %s", inputFile);

    /// gomp_tls storage bug workaround - see comments in _init_threading() function!
    if (_init_threading(true)) return -1;

    try
    {
        _processFile(ptr, inputFile, outputFile);
    }
    catch (const runtime_error &e)
    {
        const char *err = e.what();
        // An exception occurred during processing, return the error message
        LOGV("JNI exception in SoundTouch::processFile: %s", err);
        _setErrmsg(err);
        return -1;
    }


    env->ReleaseStringUTFChars(jinputFile, inputFile);
    env->ReleaseStringUTFChars(joutputFile, outputFile);

    return 0;
}

Sunting:

Setelah melakukan apa yang disarankan Alex Cohn, saya mendapatkan kesalahan berikut:

Perintah build gagal.

Error while executing process /Users/daniele/Library/Android/sdk/ndk-bundle/ndk-build with arguments {NDK_PROJECT_PATH=null APP_BUILD_SCRIPT=/Users/daniele/Developer/AndroidProjects/Chords2/app/jni/Android.mk NDK_APPLICATION_MK=/Users/daniele/Developer/AndroidProjects/Chords2/app/jni/Application.mk APP_ABI=armeabi-v7a NDK_ALL_ABIS=armeabi-v7a NDK_DEBUG=0 APP_PLATFORM=android-21 NDK_OUT=/Users/daniele/Developer/AndroidProjects/Chords2/app/build/intermediates/ndkBuild/release/obj NDK_LIBS_OUT=/Users/daniele/Developer/AndroidProjects/Chords2/app/build/intermediates/ndkBuild/release/lib APP_SHORT_COMMANDS=false LOCAL_SHORT_COMMANDS=false -B -n}
rm -f /Users/daniele/Developer/AndroidProjects/Chords2/app/build/intermediates/ndkBuild/release/lib/armeabi-v7a/*
rm -f /Users/daniele/Developer/AndroidProjects/Chords2/app/build/intermediates/ndkBuild/release/lib/armeabi-v7a/gdbserver
rm -f /Users/daniele/Developer/AndroidProjects/Chords2/app/build/intermediates/ndkBuild/release/lib/armeabi-v7a/gdb.setup
mkdir -p /Users/daniele/Developer/AndroidProjects/Chords2/app/build/intermediates/ndkBuild/release/obj/local/armeabi-v7a/objs/soundtouch
echo [armeabi-v7a] "Compile++ arm  ": "soundtouch <= soundtouch-jni.cpp"
/Users/daniele/Library/Android/sdk/ndk-bundle/toolchains/llvm/prebuilt/darwin-x86_64/bin/clang++ -MMD -MP -MF /Users/daniele/Developer/AndroidProjects/Chords2/app/build/intermediates/ndkBuild/release/obj/local/armeabi-v7a/objs/soundtouch/soundtouch-jni.o.d -gcc-toolchain /Users/daniele/Library/Android/sdk/ndk-bundle/toolchains/arm-linux-androideabi-4.9/prebuilt/darwin-x86_64 -fpic -ffunction-sections -funwind-tables -fstack-protector-strong -Wno-invalid-command-line-argument -Wno-unused-command-line-argument -no-canonical-prefixes -fno-integrated-as -g -target armv7-none-linux-androideabi -march=armv7-a -mfloat-abi=softfp -mfpu=vfpv3-d16 -fno-exceptions -fno-rtti -marm -O2 -DNDEBUG  -I/Users/daniele/Library/Android/sdk/ndk-bundle/sources/cxx-stl/stlport/stlport -I/Users/daniele/Library/Android/sdk/ndk-bundle/sources/cxx-stl//gabi++/include -I/Users/daniele/Developer/AndroidProjects/Chords2/app/jni -DANDROID -fvisibility=hidden -I ../../../include -fdata-sections -ffunction-sections -Wa,--noexecstack -Wformat -Werror=format-security  -frtti   -fexceptions  -isystem /Users/daniele/Library/Android/sdk/ndk-mbundake: *** No rule to make target `/Users/daniele/Delveeloper/platforms/android-/AndroidProjects/Chords2/app/jni/../../SoundTouch/AAFilter.cpp', needed by `/Users/daniele/Developer/AndroidProjects/Chords2/app/build/intermedi2ates/ndkBuild/1/arch-arm/usr/include -c release/obj/local/armeabi-v7a/objs/soun /Users/dtdaniele/Douch/__/__/SoeveloundTouch/AAFpilter.o'.  Stop.
er/AndroidProjects/Chords2/app/jni/soundtouch-jni.cpp -o /Users/daniele/Developer/AndroidProjects/Chords2/app/build/intermediates/ndkBuild/release/obj/local/armeabi-v7a/objs/soundtouch/soundtouch-jni.o 

Perintah build gagal.

Error while executing process /Users/daniele/Library/Android/sdk/ndk-bundle/ndk-build with arguments {NDK_PROJECT_PATH=null APP_BUILD_SCRIPT=/Users/daniele/Developer/AndroidProjects/Chords2/app/jni/Android.mk NDK_APPLICATION_MK=/Users/daniele/Developer/AndroidProjects/Chords2/app/jni/Application.mk APP_ABI=armeabi-v7a NDK_ALL_ABIS=armeabi-v7a NDK_DEBUG=1 APP_PLATFORM=android-21 NDK_OUT=/Users/daniele/Developer/AndroidProjects/Chords2/app/build/intermediates/ndkBuild/debug/obj NDK_LIBS_OUT=/Users/daniele/Developer/AndroidProjects/Chords2/app/build/intermediates/ndkBuild/debug/lib APP_SHORT_COMMANDS=false LOCAL_SHORT_COMMANDS=false -B -n}
rm -f /Users/daniele/Developer/AndroidProjects/Chords2/app/build/intermediates/ndkBuild/debug/lib/armeabi-v7a/*
rm -f /Users/daniele/Developer/AndroidProjects/Chords2/app/build/intermediates/ndkBuild/debug/lib/armeabi-v7a/gdbserver
rm -f /Users/daniele/Developer/AndroidProjects/Chords2/app/build/intermediates/ndkBuild/debug/lib/armeabi-v7a/gdb.setup
mkdir -p /Users/daniele/Developer/AndroidProjects/Chords2/app/build/intermediates/ndkBuild/debug/lib/armeabi-v7a
echo [armeabi-v7a] "Gdbserver      ": "[arm-linux-androideabi] /Users/daniele/Developer/AndroidProjects/Chords2/app/build/intermediates/ndkBuild/debug/lib/armeabi-v7a/gdbserver"
install -p /Users/daniele/Library/Android/sdk/ndk-bundle/prebuilt/android-arm/gdbserver/gdbserver /Users/daniele/Developer/AndroidProjects/Chords2/app/build/intermediates/ndkBuild/debug/lib/armeabi-v7a/gdbserver
echo [armeabi-v7a] "Gdbsetup       ": "/Users/daniele/Developer/AndroidProjects/Chords2/app/build/intermediates/ndkBuild/debug/lib/armeabi-v7a/gdb.setup"
echo "set solib-search-path /Users/daniele/Developer/AndroidProjects/Chords2/app/build/intermediates/ndkBuild/debug/obj/local/armeabi-v7a" > /Users/daniele/Developer/AndroidProjects/Chords2/app/build/intermediates/ndkBuild/debug/lib/armeabi-v7a/gdb.setup
echo "directory /Users/daniele/Library/Android/sdk/ndk-bundle/platforms/android-21/arch-arm/usr/include /Users/daniele/Library/Android/sdk/ndk-bundle/sources/cxx-stl/stlport/stlport /Users/daniele/Library/Android/sdk/ndk-bundle/sources/cxx-stl//gabi++/include /Users/daniele/Developer/AndroidProjects/Chords2/app/jni" >> /Users/daniele/Developer/AndroidProjects/Chords2/app/build/intermediates/ndkBuild/debug/lib/armeabi-v7a/gdb.setup
mkdir -p /Users/daniele/Developer/AndroidProjects/Chords2/app/build/intermediates/ndkBuild/debug/obj/local/armeabi-v7a/objs/soundtouch
echo [armeabi-v7a] "Compile++ arm  ": "soundtouch <= soundtouch-jni.cpp"
/Users/daniele/Library/Android/sdk/ndk-bundle/toolchains/llvm/prebuilt/darwin-x86_64/bin/clang++ -MMD -MP -MF /Users/daniele/Developer/Androidmake: *** No rule to make target `/Users/daniele/Developer/AndroidProjects/Chords2/app/jniPro/../../SojeundTouch/AAFilter.cpp'c, ts/nCheeded by `o/Usrdsers/daniele/Develo2/apper/AndroidpProjects/Chords2/app/build/intermediates/ndkBuild//bdebug/obj/local/uiarmeabi-v7a/objs/soundtouch/__/__/SoundldTouch/AAFilter.o'.  Stop.
/intermediates/ndkBuild/debug/obj/local/armeabi-v7a/objs/soundtouch/soundtouch-jni.o.d -gcc-toolchain /Users/daniele/Library/Android/sdk/ndk-bundle/toolchains/arm-linux-androideabi-4.9/prebuilt/darwin-x86_64 -fpic -ffunction-sections -funwind-tables -fstack-protector-strong -Wno-invalid-command-line-argument -Wno-unused-command-line-argument -no-canonical-prefixes -fno-integrated-as -g -target armv7-none-linux-androideabi -march=armv7-a -mfloat-abi=softfp -mfpu=vfpv3-d16 -fno-exceptions -fno-rtti -marm -O2 -DNDEBUG  -I/Users/daniele/Library/Android/sdk/ndk-bundle/sources/cxx-stl/stlport/stlport -I/Users/daniele/Library/Android/sdk/ndk-bundle/sources/cxx-stl//gabi++/include -I/Users/daniele/Developer/AndroidProjects/Chords2/app/jni -DANDROID -fvisibility=hidden -I ../../../include -fdata-sections -ffunction-sections -Wa,--noexecstack -Wformat -Werror=format-security  -frtti   -fexceptions  -isystem /Users/daniele/Library/Android/sdk/ndk-bundle/platforms/android-21/arch-arm/usr/include -c  /Users/daniele/Developer/AndroidProjects/Chords2/app/jni/soundtouch-jni.cpp -o /Users/daniele/Developer/AndroidProjects/Chords2/app/build/intermediates/ndkBuild/debug/obj/local/armeabi-v7a/objs/soundtouch/soundtouch-jni.o

Harap diperhatikan: Saya mengkompilasi Perpustakaan Soundtouch menggunakan ndk-build di Ubuntu Linux, lalu menyalinnya ke macOS tempat saya biasanya bekerja

Ada petunjuk tentang cara memperbaikinya?


person Daniele    schedule 05.09.2017    source sumber
comment
Bisakah Anda menyertakan file header yang mengekspor fungsi C asli. Dan log kesalahan (logcat) di sekitar kesalahan (memiliki pesan tambahan yang akan membantu mendiagnosis masalah)   -  person Richard Critten    schedule 05.09.2017
comment
@RichardCritten maksud Anda soundtouuch-jni.cpp?   -  person Daniele    schedule 05.09.2017
comment
Saya ingin melihat deklarasi C lengkap getVersionString   -  person Richard Critten    schedule 05.09.2017
comment
Saya tidak tahu persis di mana menemukan fungsi getVersionString. Pokoknya semua fungsi memberikan kesalahan   -  person Daniele    schedule 05.09.2017
comment
Kebanyakan seperti kompiler/penghubung telah mengekspor simbol di libsoundtouch dengan nama yang hancur. Gunakan nm untuk melihat nama fungsi yang diekspor oleh modul sebenarnya. Aspek JNI yang terkenal membuat frustrasi. Anda mungkin bisa mengekspor nama yang tidak rusak dengan menggunakan extern C {}   -  person JJF    schedule 05.09.2017
comment
@JJF Saya akan mencoba membangunnya kembali   -  person Daniele    schedule 05.09.2017
comment
Saya pikir Anda memiliki lebih banyak pekerjaan yang harus dilakukan. Dari apa yang saya tahu bahwa perpustakaan yang Anda coba gunakan tidak mendukung konvensi panggilan C (yang diperlukan JNI) jadi Anda harus menulis jembatan di C yang dipanggil JVM yang pada gilirannya memanggil CPP kode. Lihat github.com/bytedeco/javacpp untuk mengetahui tantangan yang Anda hadapi.   -  person JJF    schedule 05.09.2017
comment
@JJF, bisakah Anda melihat kode sumbernya? ada contoh android di sana yang berfungsi. Mungkin Anda bisa mendapatkan info lebih lanjut dari sana. Saya mengkompilasi dan membangunnya mengikuti panduan di README. Berikut tautan kode sumbernya: surina.net/soundtouch/sourcecode.html   -  person Daniele    schedule 05.09.2017
comment
Kelas SoundTouch Anda ada di paket apa? Sampel tersebut memerlukan kelas SoundTouch dalam paket net.surina.soundtouch. Nama paket adalah bagian dari nama fungsi JNI.   -  person JJF    schedule 05.09.2017
comment
Dan soundtouch-jni.cpp menyediakan nama yang tidak diubah untuk Anda gunakan. misalnya eksternal C DLL_PUBLIC jstring Java_net_surina_soundtouch_SoundTouch_getVersionString(JNIEnv *env, jobject thiz); Catat nama paket yang disertakan dalam nama fungsi.   -  person JJF    schedule 05.09.2017
comment
@JFF Saya melihat memang benar saya mendapatkan semua nama fungsi yang tidak terurai. Apakah karena kesalahan saat kompilasi?   -  person Daniele    schedule 06.09.2017
comment
@JFF Saya menambahkan soundtouuch-jni.cpp saya di pertanyaan agar Anda dapat melihatnya   -  person Daniele    schedule 06.09.2017
comment
Apakah orang yang tidak setuju akan menjelaskan alasannya?   -  person Daniele    schedule 06.09.2017
comment
Ada banyak sekali jawaban yang mengatasi pesan kesalahan 'Tidak dapat menyelesaikan fungsi JNI yang sesuai'. Harap pertimbangkan yang ini juga: stackoverflow.com/a/44225181/192373. TL;NR: Android Studio tidak akan memeriksa file .so Anda untuk metode asli, ia hanya dapat menemukannya jika Anda menggunakan externalNativeBuild yang terintegrasi.   -  person Alex Cohn    schedule 06.09.2017
comment
@AlexCohn Begitu, jadi kesalahan itu seharusnya terkait dengan Android Studio dan semuanya akan baik-baik saja setelah saya menjalankan apk? Haruskah aku mengabaikannya saja? Tolong beritahu saya lebih banyak tentang externalNativeBuild hal ini, Bagaimana cara menerapkannya? Apakah ini akan memungkinkan Android Studio untuk menyelesaikan fungsi jni tersebut?   -  person Daniele    schedule 07.09.2017
comment
@AlexCohn Seperti yang Anda sarankan di sini: stackoverflow.com/a/44225181/6427630 Saya menggunakan @SuppressWarnings() untuk membuat apk tetapi ketika Saya mencoba menjalankannya saya mendapatkan java.lang.UnsatisfiedLinkError: dalvik.system.PathClassLoader[DexPathList[[zip file "/data/app/com.dancam.chords-1/base.apk"],nativeLibraryDirectories=[/data/app/com.dancam.chords-1/lib/x86, /system/lib, /vendor/lib]]] couldn't find "libsoundtouch.so" di baris System.loadLibrary("soundtouch"). Adakah yang tahu mengapa ini terjadi? File .so ada di dalam folder app/jniLibs saya   -  person Daniele    schedule 07.09.2017
comment
Ya, saya yakin beralih ke externalNativeBuild adalah cara terbaik untuk memperbaiki masalah Anda.   -  person Alex Cohn    schedule 07.09.2017
comment
Berdasarkan tangkapan layar Anda, file .so ada di folder app/libs. Anda dapat mengonfigurasi gradle untuk mengambilnya dari sana, namun jauh lebih sehat jika mengaktifkan build terintegrasi.   -  person Alex Cohn    schedule 07.09.2017
comment
Pertanyaan Anda sangat membingungkan. Log Anda menyarankan Mac, tetapi tangkapan layarnya berasal dari Linux. Log sepertinya berasal dari lebih dari satu perintah yang saling terkait. Dan argumen -B -n sangat aneh. Bagaimana Anda mendapatkan log ini?   -  person Alex Cohn    schedule 09.09.2017
comment
@AlexCohn Anda benar, maaf karena tidak mengatakan itu. Saya sebenarnya mengkompilasi perpustakaan di Ubuntu Linux, dan kemudian menyalinnya di Mac tempat saya biasanya bekerja   -  person Daniele    schedule 09.09.2017


Jawaban (2)


Saya melihat Anda mengalami masalah dalam membangun libsoundtouch.so di Android Studio. Ini terjadi, mis. ketika skrip pembangunan perpustakaan bagian ketiga memerlukan lingkungan khusus. Misalnya. satu-satunya cara yang didukung untuk membangun webrtc untuk Android adalah di Linux 64-bit.

Dalam hal ini, Anda dapat menggunakan perpustakaan bawaan. Letakkan di folder jniLibs di bawah proyek Anda (jniLibs/armeabi-v7a/libsoundtouch.so dll.), atau setel folder khusus untuk jniLibs di build.gradle (di blok android {}):

sourceSets.main.jniLibs.srcDir 'libs'

Anda tidak boleh menggunakan externalNativeBuild.ndkBuild.path bersamaan dengan ini.

person Alex Cohn    schedule 09.09.2017
comment
Sekali lagi terima kasih Alex, tapi apa saja perpustakaan bawaannya? Yang saya gunakan adalah yang saya buat di Linux 64-bit - person Daniele; 09.09.2017
comment
Ya, yang Anda salin dari mesin build Linux - person Alex Cohn; 09.09.2017
comment
Pembangunan gradle akhirnya berhasil, terima kasih untuk itu. Saya mengalami masalah saat memanggil metode terkait perpustakaan. Silakan periksa pertanyaan yang telah diedit - person Daniele; 10.09.2017
comment
Silakan buka pertanyaan terpisah, gratis di situs ini. Pertanyaan-pertanyaan ini dimaksudkan untuk membantu orang lain juga. Dengan mengubah cerita berulang kali, Anda membuatnya sangat sulit untuk diikuti. - person Alex Cohn; 10.09.2017

Anda harus menyiapkan proyek gradle Anda untuk membangun perpustakaan C++.

Silakan tambahkan ke build.gradle Anda baris berikut (di dalam blok android {}):

externalNativeBuild.ndkBuild.path = 'jni/Android.mk'

(dengan asumsi jalur ~/AndroidStudioProjects/Chords2/app/build.gradle dan ~/AndroidStudioProjects/Chords2/app/jni/Android.mk).

Untuk mengurangi waktu kompilasi dan ukuran APK, Anda dapat memfilter ABI yang tidak Anda gunakan, setidaknya saat melakukan debug:

ndk { abiFilters 'armeabi-v7a' }

Baris ini masuk ke dalam blok defaultConfig {}.

Bagaimanapun, setelah APK siap, Anda dapat menggunakan Build/Analyze APK dari menu Android Studio dan memeriksa apakah semua file .so dimasukkan ke dalamnya.

person Alex Cohn    schedule 07.09.2017
comment
Terima kasih, saya akan mencobanya sebentar lagi - person Daniele; 07.09.2017
comment
Silakan lihat pertanyaan yang telah diedit. Saya menghadapi masalah tersebut setelah melakukan apa yang Anda katakan kepada saya. Tahukah Anda cara mengatasinya? - person Daniele; 07.09.2017
comment
aturan pertama: jangan pernah menggunakan spasi di jalur saat Anda menangani Android NDK (dan SDK). - person Alex Cohn; 07.09.2017
comment
Terima kasih, mengubah nama direktori itu, membawa saya sedikit lebih jauh. Setidaknya sekarang mulai menghapus armeabi-v7a barang. Namun masih tergantung di suatu tempat. Silakan periksa pertanyaan yang diperbarui, dengan log baru - person Daniele; 07.09.2017
comment
Cobalah untuk menghapus direktori build dan membangun kembali semuanya. - person Alex Cohn; 07.09.2017
comment
Saya mencoba memahami pesan kesalahan apa yang Anda tempelkan, tetapi pesan tersebut tidak masuk akal. Saya tidak tahu dari mana -B -n datang untuk perintah ndk-build yang terintegrasi. - person Alex Cohn; 07.09.2017
comment
Saya mencoba memperbarui NDK ke versi terbaru. Jika ini tidak memperbaikinya, saya mungkin akan memberikan hadiah, saya tidak tahu harus berbuat apa lagi. Saya juga memeriksa banyak panduan tentang cara mengimpor .so perpustakaan dan tampaknya cukup mudah. Tidak tahu mengapa saya mendapatkan semua kesalahan ini - person Daniele; 08.09.2017
comment
Setelah memperbarui NDK ke r15c saya mendapatkan log kesalahan baru yang lain untuk Anda periksa :) - person Daniele; 08.09.2017