Android移植源码APP(USB CAMERA APK)问题总结

时间:2021-01-12 16:00:02
最近公司的一个项目(行车记录仪)要求能支持USB camera(兼容uvc)预览显示。在网上浏览了一番相关知识,了解到要使android系统支持usb 摄像头,除了要打开内核中的驱动支持之外,还需要加载专门的APK才能正常显示。考虑到需要系统内部集成usb camera 的APK,且出现问题时最好能进行简单的调试,于是从网上下载了一个源码版本的apk,打算将其移植到系统代码中。原以为移植工作会很简单,谁知在移植的过程中一波三折,出现了不少问题,整整折腾了一整天才移植完毕。因而在此将移植过程出现的一些问题进行总结,避免以后再做移植工作时又走弯路。

1.    编译该usb camera预览APK的jni库时,系统出错:
error: undefined reference to 'AndroidBitmap_getInfo'
error: undefined reference to 'AndroidBitmap_lockPixels'
error: undefined reference to 'AndroidBitmap_unlockPixels'

查看这些错误信息,应该是涉及图像处理的一些函数未找到定义,也就是说对应的android图像处理库未被编译包含进来。到网上搜索对应的关键字,不出所料,很多人都遇到了同样的问题,给出的解决办法都是说在Android.mk中加入如下编码:
LOCAL_LDLIBS    := -ljnigraphics –llog

于是检查了一下自己的代码,Android.mk中豁然显示着:
LOCAL_LDLIBS    := -llog –ljnigraphics
Shit,你这是在玩我吗,感觉不能再爱了。
继续搜索网页,给出的答案大都是“LOCAL_LDLIBS  := -ljnigraphics –llog”。自己也做了一些尝试,但是各种改动带来的仍然是相同的编译错误提示。折腾了一个多小时,整个人都感觉不好了,这是药丸的节奏啊!
搜索关键字“ljnigraphics”吧,这下发现了端倪,不少ljnigraphics的用法都是“LOCAL_LDFLAGS += -ljnigraphics”,于是依葫芦画瓢,问题解决,编译通过。


2.    打开APK出现错误提示,log提示system/lib目录下找不到jni生成的lib库。
编译完成,下载程序打开APK,赫然出现错误提示,运行中止。打开log发现错误提示:“Couldn't load libImageProc from loader dalvik.system.PathClassLoader[DexPathList[[zip file "/system/app/simplewebcam.apk"],nativeLibraryDirectories=[/vendor/lib, /system/lib]]]: findLibrary returned null”。
打开adb shell查看手机,的确在system/lib目录下没有libImageProc.so这个文件。于是到编译生成的out目录中查找,在system/lib目录下也没有这个文件。怎么样才能将编译生成的libImageProc.so库自动放置在system/lib目录下呢?还是看看网络上别人怎么弄的吧。
万能的网络,别人早已给出了解决办法:http://www.360doc.com/content/14/0303/15/7044580_357359313.shtml
简单总结起来就是:
(1)    so是第三方提供的,别人已经编译好了的,使用PRODUCT_COPY_FILES拷贝到需要的文件夹下;
(2)    so是源码,并且需要放在代码中编译,则使用“PRODUCT_PACKAGES +=”的方式。注意这里的名字要求和模块的Android.mk中,LOCAL_MODULE指定生成的文件名称相同,同时,还要求模块的Android.mk中LOCAL_MODULE_TAGS := optional。

按照别人的指示在PRODUCT_PACKAGES加入代码,编译完成后再检查,system/lib目录下已经有libImageProc.so这个文件了。

3.    打开APK仍然出现错误,log仍然提示system/lib目录下找不到lib库。
你没看错,我也没写错,第3个错误和2个错误提示完全一样。下载完开机,进入apk出错了,检查Log提示,和第2个错误完全一样。使用adb shell连接机器,ls -l /system/lib/libImageProc*命令后看到了libImageProc.so文件。
哥很愤怒,哥很生气,哥对android吼道:你TM瞎了眼了吗,libImageProc不是在这吗?你怎么就认不出来?
可是不论哥怎么咆哮,android仍然冷冷地看着我,鸟都不鸟哥一下,该出错还是出错。

没办法,百度吧,终于有一位好基友告诉了我解决办法:http://blog.csdn.net/treasure3334/article/details/17170927

他的总结是:NDK开发中,库的命名需要遵守规则:
jni生成的.so文件在编译后会自动添加上前缀lib和后缀.so,所以Android.mk文件中通过LOCAL_MODULE定义库的名字时,不要加前缀lib和后缀 .so。

调用System.loadLibrary()时,参数与LOCAL_MODULE定义的名字要保持一致。

如果定义LOCAL_MODULE时添加了前缀lib,则在生成 .so 文件时,不会再重复添加前缀lib。这时候,自动生成的 .so 文件只比定义多了一个后缀 .so。

但是在java调用中,仍然不要加前缀lib,也就是与LOCAL_MODULE不加前缀时的情形是一样的。


    检查我的代码,发现系统里果真是System.loadLibrary("libImageProc"),将前缀lib去掉后,APK顺利执行成功。