Native程序中引入Binder库
目前最新的ndk环境中,不包含binder库。
- 下载安卓源码,将下面两句加入Android.mk文件,在源码中利用mm命令作为子模块进行单独编译,优点:简单,缺点:编译速度慢,需要依赖安卓源码,不利于协同开发
LOCAL_SHARED_LIBRARIES := libutils libcutils libbinder liblog
LOCAL_C_INCLUDES += frameworks/native/include system/core/include
- 手动提取Binder库文件,并且导入Native程序,优点:编译速度快,不需要下载源码,缺点:手动提取库麻烦。
以下是第二种方式的教程
1.导入动态链接库
连接手机,直接pull出这几个动态链接库
adb pull /system/lib/libbinder.so ./
adb pull /system/lib/libcutils.so ./
adb pull /system/lib/libutils.so ./
如果没有手机源码,建议在Google Git上,在/system/lib中找以上三个动态链接库,注意找一下,32位和64位。
我这里是将动态链接库放在native程序下libs/binder_libs,在Android.mk引入动态链接库。
文件如下:
include $(CLEAR_VARS)
LOCAL_MODULE := libutils
LOCAL_SRC_FILES := libs/binder_libs/$(TARGET_ARCH_ABI)/libutils.so
include $(PREBUILT_SHARED_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := libcutils
LOCAL_SRC_FILES := libs/binder_libs/$(TARGET_ARCH_ABI)/libcutils.so
include $(PREBUILT_SHARED_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := libbinder
LOCAL_SRC_FILES := libs/binder_libs/$(TARGET_ARCH_ABI)/libbinder.so
include $(PREBUILT_SHARED_LIBRARY)
//主模块
LOCAL_SHARED_LIBRARIES := libcutils libutils libbinder
2.导入头文件
动态链接库需要有头文件,在Google Git里面找以下两个目录的文件,导入项目include/binder_header。
frameworks/native/include
system/core/include
在Android.mk文件中用LOCAL_C_INCLUDES指定头文件的位置。
LOCAL_C_INCLUDES += $(LOCAL_PATH)/include/binder_header
噩梦开始,各种报错,巴巴好久。。。没解决。
找到这个库,打包好了,很开心,另一个噩梦的开始(微笑),草。
https://github.com/feicong/ndk
导入,写好mk文件,编译,和ndk库的log.h冲突
jni/include/cutils/log.h:469:3: error: typedef redefinition with different types ('enum log_id_t' vs 'enum log_id')
} log_id_t;
^
/home/mi/Android/Sdk/ndk-bundle/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/include/android/log.h:162:3: note: previous definition is here
} log_id_t;
解决:曲线救国, 在cutils目录下, 定义ALog.h,把所有的#include<cutils/log.h>切换成#include "ALog.h",都替换了。
ALog.h文件如下:
#pragma once
#include<android/log.h>
#define LOG_TAG "debug log"
#define LOGI(fmt, args...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, fmt, ##args)
#define LOGD(fmt, args...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, fmt, ##args)
#define LOGE(fmt, args...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, fmt, ##args)
Android.mk文件如下:
//主模块加入这条
LOCAL_LDLIBS := -ldl -llog
编译,草,又有问题,和C++库定义冲突。
jni/include/utils/Unicode.h:25:18: error: cannot combine with previous 'type-name' declaration specifier
typedef uint32_t char32_t;
^
jni/include/utils/Unicode.h:25:1: warning: typedef requires a name [-Wmissing-declarations]
typedef uint32_t char32_t;
^~~~~~~~~~~~~~~~~~~~~~~~~
jni/include/utils/Unicode.h:26:18: error: cannot combine with previous 'type-name' declaration specifier
typedef uint16_t char16_t;
^
jni/include/utils/Unicode.h:26:1: warning: typedef requires a name [-Wmissing-declarations]
typedef uint16_t char16_t;
注释掉Unicode.h的,工具链接错误,草,真没法了。。。
ld: error: found local symbol '_bss_end__' in global part of symbol table in file ./obj/local/arm64-v8a/libutils.so
ld: error: found local symbol '__bss_start' in global part of symbol table in file ./obj/local/arm64-v8a/libutils.so
ld: error: found local symbol '__end__' in global part of symbol table in file ./obj/local/arm64-v8a/libutils.so
ld: error: found local symbol '__bss_start__' in global part of symbol table in file ./obj/local/arm64-v8a/libutils.so
ld: error: found local symbol '_edata' in global part of symbol table in file ./obj/local/arm64-v8a/libutils.so
ld: error: found local symbol '__bss_end__' in global part of symbol table in file ./obj/local/arm64-v8a/libutils.so
ld: error: found local symbol '_end' in global part of symbol table in file ./obj/local/arm64-v8a/libutils.so
ld: error: found local symbol '_bss_end__' in global part of symbol table in file ./obj/local/arm64-v8a/libcutils.so
ld: error: found local symbol '__bss_start__' in global part of symbol table in file ./obj/local/arm64-v8a/libcutils.so
ld: error: found local symbol '__bss_end__' in global part of symbol table in file ./obj/local/arm64-v8a/libcutils.so
ld: error: found local symbol '__bss_start' in global part of symbol table in file ./obj/local/arm64-v8a/libcutils.so
ld: error: found local symbol '__end__' in global part of symbol table in file ./obj/local/arm64-v8a/libcutils.so
ld: error: found local symbol '_edata' in global part of symbol table in file ./obj/local/arm64-v8a/libcutils.so
ld: error: found local symbol '_end' in global part of symbol table in file ./obj/local/arm64-v8a/libcutils.so
ld: error: found local symbol '__end__' in global part of symbol table in file ./obj/local/arm64-v8a/libbinder.so
ld: error: found local symbol '__bss_end__' in global part of symbol table in file ./obj/local/arm64-v8a/libbinder.so
ld: error: found local symbol '__bss_start' in global part of symbol table in file ./obj/local/arm64-v8a/libbinder.so
解决办法:在Android.mk文件加入LOCAL_LDFLAGS := -fuse-ld=gold就可以了,气死了。。。