JNI层调用so
JNI层
#include <dlfcn.h>
void hw_dll_call() { LOGD("------------------hw_dll_call()"); int (*Func)(void) = NULL; void * func_handle = NULL; func_handle = dlopen("Hoyita.so", RTLD_LAZY); if (!func_handle) { LOGE("Fail to dlopen Hoyita.so: %s\n", dlerror()); return; } Func = dlsym(func_handle, "test_aa"); if (Func == NULL) { LOGE("Fail to dlsym test_aa"); return; } (*Func)(); dlclose(func_handle); } void Java_com_example_hoyihu_MainActivity_test(JNIEnv* env, jobject thiz) { LOGD("----------native----test()"); hw_dll_call(); }
//Android.mk LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_SRC_FILES += \ test.c LOCAL_SHARED_LIBRARIES:= \ libcutils \ liblog LOCAL_MODULE := Hoyita include $(BUILD_SHARED_LIBRARY)
//test.c
#include <utils/Log.h> void test_aa() { ALOGD("------------------test_aa()"); }
$ source build/envsetup.sh
$ choosecombo release kirin970 eng normal singleAP arm64
$ make -j64 Hoyita
生成/system/lib/Hoyita.so和/system/lib64/Hoyita.so
$ adb push system/lib/Hoyita.so /system/lib/
$ adb push system/lib64/Hoyita.so /system/lib64/
01-09 14:59:04.467 2651 2651 E Test : Fail to dlopen Hoyita.so: dlopen failed: library "/system/lib64/Hoyita.so" needed or dlopened by "/data/app/com.example.hoyihu-QArM44W_1l
W6PkWnI46V1A==/lib/arm/libdaemon-jni.so" is not accessible for the namespace "classloader-namespace"
谷歌从Android N开始,除了那些在Android NDK提供的库之外,限制了应用对系统私有库的加载。既然是限制了,想通过以前的方法去加载库已经行不通了。所以目前的解决方法就是把应用需要加载的库和需要依赖的库从系统中pull出来,然后集成到自己的应用当中
解决办法则是将自己的so加入到允许路径的白名单里面,具体操作为,如果不改代码实现,则导出设备的/vendor/etc/public.libraries.txt 或/etc/public.libraries.txt文件,将so名字添加进去,在push到设备,重启即可。