将so打包进apk ,网上常见的就是 在源码中有c代码,编译出一个so,然后打进apk,也是网上大家转来转去的那几篇文章,因为一致只做纯java开发,这种方法没有试过。
如果是第三方so ,则有诸多麻烦。
一种就是 其他同事现在的方法,在eclipse开发,那么libs/armeabi下的so 自动弄进去了,真是简单又方便。
另外一种就是要把so拷贝到编译环境的某个目录,在编译代码时整合进去。
客户方给了一个so,不知道开发细节,需要编进去。我习惯了在代码树下开发,刚开始并没有注意配置so,结果编译正常,安装正常,但是一旦 loadLibary ,就exception: load library renturn null。
解压发现apk发现,里面并没有源码对应的libs/armeabi/xxx.so,看来并没有打包进去。
在纠结中实战,找到如下实用方法;
1 copy 你的so 到out/target/product/generic/system/lib 。 这个目录是你没有修改过TARGET_PRODUCT的情况下。
如果你的TARGET_PRODUCT是 XXXYYY,则要去out/target/product/XXXYYY/system/lib 。
ps:这一步其实可以在第二步中的mk文件中用代码执行,同事给的参考为:
$(shell mkdir -p $(TARGET_OUT)/../obj/STATIC_LIBRARIES/$(LOCAL_MODULE)_intermediates )
$(shell cp $(LOCAL_PATH)/lib/libmap-encrypt.a $(TARGET_OUT)/../obj/STATIC_LIBRARIES/$(LOCAL_MODULE)_intermediates/$(LOCAL_MODULE).a)
晚上回去试一试。
2 在app代码中创建mk文件,文件名可随意,但建议和so同名吧 。 格式如下:
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE:= libmupdf
红色的libmupdf是你要加载的so名称,也就是out/target/product/generic/system/lib下的so名称。
一个so对应一个mk,我们习惯把n个mk放在jni目录下。这个jni目录与app的android.mk 同级。
3 在app的Android.mk中 需要有这样的声明
LOCAL_JNI_SHARED_LIBRARIES := libmupdf ,libmupdf为第二步中声明的LOCAL_MODULE如果是多个 ,用空格隔开
还有这一句:
include $(call all-makefiles-under,$(LOCAL_PATH))
4 这样编译后,即使你的源码中没有so,在生成的apk会自动建eStore.apk_FILES/lib/armeabi ,下面便是你想加载的so,只可能是第一步中的目录拷贝而来。
5 install -r 时可能报 INSTALL_FAILED_DEXOPT 。 原来在模拟器下开发,/data太小, 重新启动模拟器加 wipe-data 解决。
这个问题是解决了,但是对Android.mk的语法并不了解。以后遇到此类问题,估计还要纠结 ,555
有时间学习学习去