我如何设置Android Studio使用本地库
How do I setup Android Studio to use native libraries?
The Point:
我想从Java调用一个C/c++函数。
我做什么:
-
我能够使用"javah"程序生成一个。h文件。它正确地输出了我的头文件。完美的。我添加了两个.c文件,其中包括这个头文件,其中只有一个实现了这个函数。由于Android NDK构建系统中的一个bug,第二个是一个完全空的。c文件。
-
我使用Android NDK"NDK -build"脚本为多个不同的平台生成。so文件。
-
我将这些库文件(在它们各自的文件夹中)添加到我的Android Studio项目的jniLibs文件夹中。Gradle看到它们,并在构建时正确地将它们添加到我的.apk文件中。
-
在我的应用程序源代码中,我使用
static { System.loadLibrary("testLib"); }
。(是的,这是正确的文件名)。
问题:
当我尝试调用本机函数(在java中定义并在c++中实现)时,我得到以下异常:
java.lang.UnsatisfiedLinkError: Native method not found:
com.example.nativeapp.MainActivity.testNativeMethod:()Ljava/lang/String;"
这就是事情变得奇怪的地方:/:我用NDK成功编译,用Gradle成功构建,在我的应用程序代码中用Java成功地"loadLibrary"。但是,当简单地调用函数"testnative emethod();"时,我就会得到运行时异常和应用程序崩溃。
这是我的"javah"生成的头文件:
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_example_nativeapp_MainActivity */
#ifndef _Included_com_example_nativeapp_MainActivity
#define _Included_com_example_nativeapp_MainActivity
#ifdef __cplusplus
extern "C" {
#endif
#undef com_example_nativeapp_MainActivity_MODE_PRIVATE
#define com_example_nativeapp_MainActivity_MODE_PRIVATE 0L
#undef com_example_nativeapp_MainActivity_MODE_WORLD_READABLE
#define com_example_nativeapp_MainActivity_MODE_WORLD_READABLE 1L
#undef com_example_nativeapp_MainActivity_MODE_WORLD_WRITEABLE
#define com_example_nativeapp_MainActivity_MODE_WORLD_WRITEABLE 2L
#undef com_example_nativeapp_MainActivity_MODE_APPEND
#define com_example_nativeapp_MainActivity_MODE_APPEND 32768L
#undef com_example_nativeapp_MainActivity_MODE_MULTI_PROCESS
#define com_example_nativeapp_MainActivity_MODE_MULTI_PROCESS 4L
#undef com_example_nativeapp_MainActivity_MODE_ENABLE_WRITE_AHEAD_LOGGING
#define com_example_nativeapp_MainActivity_MODE_ENABLE_WRITE_AHEAD_LOGGING 8L
#undef com_example_nativeapp_MainActivity_BIND_AUTO_CREATE
#define com_example_nativeapp_MainActivity_BIND_AUTO_CREATE 1L
#undef com_example_nativeapp_MainActivity_BIND_DEBUG_UNBIND
#define com_example_nativeapp_MainActivity_BIND_DEBUG_UNBIND 2L
#undef com_example_nativeapp_MainActivity_BIND_NOT_FOREGROUND
#define com_example_nativeapp_MainActivity_BIND_NOT_FOREGROUND 4L
#undef com_example_nativeapp_MainActivity_BIND_ABOVE_CLIENT
#define com_example_nativeapp_MainActivity_BIND_ABOVE_CLIENT 8L
#undef com_example_nativeapp_MainActivity_BIND_ALLOW_OOM_MANAGEMENT
#define com_example_nativeapp_MainActivity_BIND_ALLOW_OOM_MANAGEMENT 16L
#undef com_example_nativeapp_MainActivity_BIND_WAIVE_PRIORITY
#define com_example_nativeapp_MainActivity_BIND_WAIVE_PRIORITY 32L
#undef com_example_nativeapp_MainActivity_BIND_IMPORTANT
#define com_example_nativeapp_MainActivity_BIND_IMPORTANT 64L
#undef com_example_nativeapp_MainActivity_BIND_ADJUST_WITH_ACTIVITY
#define com_example_nativeapp_MainActivity_BIND_ADJUST_WITH_ACTIVITY 128L
#undef com_example_nativeapp_MainActivity_CONTEXT_INCLUDE_CODE
#define com_example_nativeapp_MainActivity_CONTEXT_INCLUDE_CODE 1L
#undef com_example_nativeapp_MainActivity_CONTEXT_IGNORE_SECURITY
#define com_example_nativeapp_MainActivity_CONTEXT_IGNORE_SECURITY 2L
#undef com_example_nativeapp_MainActivity_CONTEXT_RESTRICTED
#define com_example_nativeapp_MainActivity_CONTEXT_RESTRICTED 4L
#undef com_example_nativeapp_MainActivity_RESULT_CANCELED
#define com_example_nativeapp_MainActivity_RESULT_CANCELED 0L
#undef com_example_nativeapp_MainActivity_RESULT_OK
#define com_example_nativeapp_MainActivity_RESULT_OK -1L
#undef com_example_nativeapp_MainActivity_RESULT_FIRST_USER
#define com_example_nativeapp_MainActivity_RESULT_FIRST_USER 1L
#undef com_example_nativeapp_MainActivity_DEFAULT_KEYS_DISABLE
#define com_example_nativeapp_MainActivity_DEFAULT_KEYS_DISABLE 0L
#undef com_example_nativeapp_MainActivity_DEFAULT_KEYS_DIALER
#define com_example_nativeapp_MainActivity_DEFAULT_KEYS_DIALER 1L
#undef com_example_nativeapp_MainActivity_DEFAULT_KEYS_SHORTCUT
#define com_example_nativeapp_MainActivity_DEFAULT_KEYS_SHORTCUT 2L
#undef com_example_nativeapp_MainActivity_DEFAULT_KEYS_SEARCH_LOCAL
#define com_example_nativeapp_MainActivity_DEFAULT_KEYS_SEARCH_LOCAL 3L
#undef com_example_nativeapp_MainActivity_DEFAULT_KEYS_SEARCH_GLOBAL
#define com_example_nativeapp_MainActivity_DEFAULT_KEYS_SEARCH_GLOBAL 4L
/*
* Class: com_example_nativeapp_MainActivity
* Method: testNativeMethod
* Signature: ()Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_com_example_nativeapp_MainActivity_testNativeMethod
(JNIEnv *, jobject);
#ifdef __cplusplus
}
#endif
#endif
这是我的。c实现文件:
#include "com_example_nativeapp_MainActivity.h"
JNIEXPORT jstring JNICALL Java_com_example_nativeapp_MainActivity_testNativeMethod(JNIEnv* environment, jobject obj)
{
return ( *env )->NewStringUTF(env, "HELLO FROM C Native!");
}
最后,这是我的。java应用程序文件:
package com.example.nativeapp;
import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.TextView;
public class MainActivity extends Activity
{
static { System.loadLibrary("testLib"); }
private TextView mDebugText;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mDebugText = (TextView)findViewById(R.id.debug_text);
// Here is where my native function call takes place. Without this, the app does (NOT) crash.
mDebugText.setText(testNativeMethod());
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
public native String testNativeMethod();
}
提前感谢。这绝对是那些打显示器类型的问题之一。
简单提醒一下:
我已经尝试过这个:https://www.youtube.com/watch?v=okLKfxfbz40 连续三次遵循步骤完美,仍然导致失败。
另外,我一直在阅读这里的Stackoverflow,没有一个问题符合我的情况。他们都在使用opencv等,我只是想做我自己的"Hello World"Android NDK库。再一次,提前感谢。
修复。
解决办法:
我把main.c改成了main.cpp文件,所以我可以使用"extern "C"。这样我就知道我正确地调用了C编译器。
这是我的新main.c文件(现在称为main.cpp)(与上面的OP源代码^^^^^比较):
extern "C"
{
#include "com_example_nativeapp_MainActivity.h"
JNIEXPORT jstring JNICALL Java_com_example_nativeapp_MainActivity_testNativeMethod(JNIEnv* env, jobject obj)
{
return env->NewStringUTF("HELLO FROM C Native!");
}
}
- Android Studio 中带有静态库的原生C++代码
- 如何在 Android Studio 4 中编译 C/C++ 原生代码
- Android Studio:如何在build.gradle中定义自定义宏(针对不同的构建变体),并让原生C / C++
- 更新后的Android Studio现在需要Clang,不再链接到GCC的库
- 如果我的手机是 ARMv8,为什么 Android Studio 会C++编译为 ARMv7?
- Android NDK - 无法在 Visual Studio 2017 中调试
- 将图像从 Android Studio 发送到 CPP
- 在 Android Studio 中使用 C++ 共享对象时出现问题
- CMake:Android Studio 原生活动项目无法在项目根目录之外找到第三方库
- C++17 标准库包括不适用于 Visual Studio 2017 中的 Android 项目
- 如何在Android Studio中将C++文件正确链接到现有的Android项目?
- 在 Android Studio 中添加 C/C++ 的包含路径
- Android Studio-在现有的旧项目中启用本机C++调试(card.io Android Source)
- 为什么只有一个库的链接器错误'multiple definitions'?在 Android Studio 中使用 CMake (3.4.1)
- 如何调试visual studio 2017生成的C++代码.android中的SO文件和其他第三方库
- Android Studio 3.5.1 和 NDK 20.0 找不到 cstdint
- 将Visual Studio 2017配置为使用现有的Android SDK和NDK组件
- 如何使用Java Native Interface在C++中导入python库-Android Studio
- Android Studio External Native Build 预编译标头
- Android Studio TextView Init C++