【发布时间】:2018-05-23 19:01:41
【问题描述】:
我已更新到 Android Studio 3.0,我正在尝试从已弃用的 NDK 迁移到 CMake,以构建我的 Android 应用的本机组件。
我已按照https://developer.android.com/studio/projects/configure-cmake.html 的指南进行操作,这是我的 CMakeLists.txt 文件:
cmake_minimum_required(VERSION 3.4.1)
add_library( # Specifies the name of the library.
myappNative
# Sets the library as a shared library.
SHARED
# Provides a relative path to your source file(s).
src/main/cpp/src
)
include_directories(src/main/cpp/include)
SET_TARGET_PROPERTIES(myappNative PROPERTIES LINKER_LANGUAGE CXX)
(最后一行不在教程中,但在添加之前我遇到了错误)。
这是我的文件夹结构:
这是我的原生方法:
public class Native {
static {
System.loadLibrary("myappNative");
}
public native static String sign(String[] tokens);
}
这是我的头文件(由javah生成):
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_myapp_system_Native */
#ifndef _Included_com_myapp_system_Native
#define _Included_com_myapp_system_Native
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: com_myapp_system_Native
* Method: sign
* Signature: ([Ljava/lang/String;)Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_com_myapp_system_Native_sign
(JNIEnv *, jclass, jobjectArray);
#ifdef __cplusplus
}
#endif
#endif
而且我有相应的 C++ 文件可以正确编译。我的 APK 包含 libmyapp.so 文件,一切看起来都符合预期。我的应用程序构建,它开始运行,它加载库:(logcat)
D/dalvikvm: Trying to load lib /data/app-lib/com.myapp.myapp-1/libmyappNative.so 0x41e09aa0
D/dalvikvm: Added shared lib /data/app-lib/com.myapp.myapp-1/libmyappNative.so 0x41e09aa0
然后,当我尝试调用本机方法时,我得到了这个:
W/dalvikvm: No implementation found for native Lcom/myapp/system/Native;.sign:([Ljava/lang/String;)Ljava/lang/String;
接下来是:
E/AndroidRuntime: FATAL EXCEPTION: com.myapp.client.queue
Process: com.myapp.myapp, PID: 19542
java.lang.UnsatisfiedLinkError: Native method not found: com.myapp.system.Native.sign:([Ljava/lang/String;)Ljava/lang/String;
at com.myapp.system.Native.sign(Native Method)
[...]
我的应用程序崩溃了。我已经看到很多关于此的问题,包括 Android NDK C++ JNI (no implementation found for native...),但这些解决方案也无济于事。
在日志中,我看到:
:app:externalNativeBuildDebug
Build myappNative armeabi-v7a
[1/1] Linking CXX shared library ../../../../build/intermediates/cmake/debug/obj/armeabi-v7a/libmyappNative.so
:app:compileDebugSources
这似乎没问题。
我还在某处读到 Proguard 可能会修改方法名称,因此我也为此添加了一条规则:
-keep class com.myapp.system.Native
我不知道它是否会改变任何东西。
这也是我的gradle文件的相关部分:
android {
compileSdkVersion 26
buildToolsVersion '26.0.2'
defaultConfig {
applicationId "com.myapp.myapp"
minSdkVersion 16
targetSdkVersion 26
versionCode 2043
versionName "2.1"
ndk {
moduleName "myappNative"
cFlags "-DNATIVE_DEBUG=1"
}
}
externalNativeBuild {
cmake {
path 'CMakeLists.txt'
}
}
}
我也尝试过实现JNI_OnLoad 方法并在标头中声明它,但似乎也没有找到,这可能是我的配置通用的线索,而不是特定方法:
No JNI_OnLoad found in /data/app-lib/com.myapp.myapp-2/libmyappNative.so 0x41e10aa0, skipping init
为什么 Android 找不到我的原生方法?
【问题讨论】:
标签: android c++ c cmake android-ndk