编译和引用so库
1.两种编译方式
- ndk-build + Android.mk + Application.mk
- CMake + CMakeList
2.Android.mk + Application.mk
(1)javac java文件的绝对路径 → 生成so库
(2)javah com.xxx.xxx.tesAdd → 生成头文件
(3) 修改头文件的后缀,并添加实现
(4)Application.mk
APP_ABI := armeabi-v7a arm64-v8a x86 x86_64
APP_MODULES := testAdd
APP_CFLAGS += -DSTDC_HEADERS
APP_PLATFORM := android-21
(5)Android.mk
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_C_INCLUDES := $(LOCAL_PATH) #头文件的路径
LOCAL_MODULE := testAdd
LOCAL_SRC_FILES := Num.cpp\
com_android_makeso_2_testAdd.cpp
LOCAL_LDLIBS := -L$(SYSROOT)/usr/lib-llog
LOCAL_ALLOW_UNDEFINED_SYMBOLS := true #不加头文件会有.o文件中的汇编问题
include $(BUILD_SHARED_LIBRARY)
(6) 编库
在当前目录运行 ndk-build
目前编这个库会有使用的问题
AndroidRuntime: FATAL EXCEPTION: main Process: com.android.makeso_2, PID: 17911 java.lang.UnsatisfiedLinkError: dlopen failed: cannot locate symbol "_ZNSt6__ndk14coutE" referenced by "/data/app/~~zMsVpovir-8ZGyyQC6QYQQ==/com.android.makeso_2-tC41E73EDKkgmsQ4flEfpw==/base.apk!/lib/arm64-v8a/libtestAdd.so"
根据查询,应该是mk文件的编译问题
和c++_static库有些关系
3.CMake + CMakeList
(1) java文件载入
public class testAdd {
static {
System.loadLibrary("testAdd");
}
testAdd() {
init();
}
public native int add(int a,int b);
public native int min(int a,int b);
public native int init();
public native int destory();
}
(2) 生成jni方法
JNIEXPORT jint JNICALL Java_com_android_makeso_12_testAdd_min
(JNIEnv *, jobject, jint, jint);
注意return!!
(3) CMakeList.txt
add_library( # Sets the name of the library.
application_makeso
# Sets the library as a shared library.
SHARED
# Provides a relative path to your source file(s).
native-lib.cpp
Num.cpp)
在build/intermediate/cmake 库找到编译出来的so库
4.so文件的使用
- 编写java文件
- 加载库
- 写native方法(so库中的实现方法需要注意函数名)
- 把so库放到jniLib(默认加载)
No implementation found for int com.android.useso.testAdd.init() (tried Java_com_android_useso_testAdd_init and Java_com_android_useso_testAdd_init__)