1. 无关紧要的话
事情的起因是项目有地理编码需求,于是下了百度地图的相关jar和so文件。本来在测试程序中直接把jar和so文件拷到相应目录下就可以了,但是将代码整合到项目里面时,发现死活没法定位。把百度地图开发需要的配置又搞了一遍,demo又研究了几遍,就是没发现问题。快急哭的时候,不经意间点开了libs/armeabi这个文件夹,才发现直接拷进去的so库都没了!原来,我们那个项目需要编写JNI接口,用NDK来编译C/C++代码生成so库,而NDK在build的时候会先把libs/armeabi清空,再重新生成so库。如果libs/armeabi有第三方库的话,(比如这次拷进去的百度地图LBS相关的库)这些第三方库就会被清掉。衰!
2. 解决办法
编写Android.mk文件,让NDK在build的时候去找第三方库,把它拷到libs/armeabi目录下。
网上找了一通,发现好些博文都说在jni目录下新建prebuilt目录,再把第三方库拷进prebuilt目录下,并且在prebuilt目录下新建并编写Android.mk,而后再jni目录下引用prebuilt里的库……云云。照着捣鼓了一番,还是——臣妾做不到啊!!
不过有些博文指出,NDK的官方文档有这方面指南,就在ndk目录的docs子目录下。我的ndk版本(android-ndk-r10d)里,Prebuilt Libraries这一章节在./docs/Programmers_Guide/html/md_3__key__topics__libraries__p_r_e_b_u_i_l_t_s.html这里。
有了官方文档的解释,基本也就清楚了。以libBaiduMapSDK.so库为例,首先在jni目录下新建一个prebuilt文件夹(名字任取),然后把第三方库拷进去。接下来打开在jni 目录下的Android.mk文件,声明预编译库模块:
include $(CLEAR_VARS) LOCAL_MODULE := BaiduMapSDK #模块名称 LOCAL_SRC_FILES := prebuilt/libBaiduMapSDK.so #注意加prebuilt/,这样才能找到libBaiduMapSDK.so include $(PREBUILT_SHARED_LIBRARY)
引用BaiduMapSDK模块:LOCAL_SHARED_LIBRARIES := liblog libcutils \ BaiduMapSDK #就是上边声明的那个模块
这样ndk-build完之后,你就可以在libs/armeabi下看到libBaiduMapSDK.so了:D
3. 后话
- Prebuilt Libraries更详尽的解释,请参考官方文档。
- 别人的解决办法:(不保证可行 :P)
- 进一步可参考:Android.mk文档规范