最近开始做Android平台下的相机开发,有别于驱动层和HAL层,我更多的是关注成像画质和虚拟预览等上层应用,整理了一点心得,感觉有必要记录一下成长的足迹。因为初学,不保证理解精准到位,请各位看官们坚定立场,大神请绕路走咯。
一、源码编译
对于自学开源软件,我已经养成了一套自己的学习法则,那肯定是下载源码—>查阅系统架构介绍(一定是官方网站为主+各路民间帖)—>扣取感兴趣小模块,导入IDE里深入分析—>再参考官网上对应部分的tutorials(好的开源软件这个部分都很赞!就像ROS)—>从编译helloworld开始学习编译源代码 —>改写代码,引用自己需要的三方库—>鉴于Android移动开发,最后一步一定是要在真机上install对应的apk咯。
1)开发环境的搭建
先确保安装好对应版本的JDK(我用jdk1.7.0_45),然后把官网上的adt-bundle-windows-x86_64-20131030下载下来,直接就可以用了!后面需要的build-tools、SDK-tools、platform-tools等软件包,就交给eclipse下的Android SDK Manager了,能保证网络通畅就行,真是一个简单粗暴但有效便捷的方法啊。
2)扣Gallery2源码
在Android-4.2.1_r1/packages/apps路径下截取Gallery2和Camera包。从4.0版本起,google将Gallery和Camera联系在了一起,编译前者的时候,后者不可获取,这从Gallery/AndroidManifest.xml文件中多处闪现的camera字眼中可见。这里,要提前在系统源码编译的/out/target/commom/obj/JAVA_LIBRARIES路径下,挖出几个后续Gallery2编译过程中所需要引用的几个静态库。分别将core_intermediates、framework_intermediates、mp4parser_intermediates、xmp_toolkit_intermediates四个路径下得classes.jar 文件分别重命名为 core_intermediates.jar、framework_intermediates.jar、mp4parser_intermediates.jar、xmp_toolkit_intermediates.jar,放入本地一个文件夹里,作为后续编译Gallery2模块源码静态库的预前准备。
3)在eclipse里面导入源码,编译
a .在eclipse里的Android Project from Existing Code里面选Gallery2文件夹,不要test。接着在项目属性的Java Build Path的Source选项下将gallerycommon和src_pd作为源代码文件夹add进入。这里我做的一件事是,在gallerycommon文件夹下,删除了原来自带的以src开头的包,新建了三个以com开头对应名称的包,然后就ctrl+a把对应路径下本地文件夹下的源java文件Paste到eclipse里对应的包名下(以防后续import时src的多余)。同时,在Build Path里面用Add Libraries将之前准备的几个jar包填进去。用Order and Export排一下序,就基本完成了第一步操作了。
b.这时,src等源文件里面还是一片红色小叉,不用着急。打开看后,发现很多都是import时文件缺损的问题,总结有两类,一类是R问题(对应的gen下面果然没有自己生成对应的R.java文件,这个先放一部),另一类就是camera相关的文件找不到的问题了,这个也等下一步解决吧。
c.查看最不该有红叉的资源文件夹,发现res/value下面的filtershow_strings.xml、photoeditor_strings.xml、strings.xml都有错误,原因是里面有重复定义!最简单粗暴的方法即是找到有错的语句,将其用<!-- -->注释掉。可以按照这种方法对values-xx开头的文件夹都做相同的处理,但参照前人的说法,支柱是简体中文的我们大可将values-zh-rCN之外的value-xx从项目中移除。剩下的rCN文件夹做上面同样的注释处理。
d.开始配置camera包了。一个导入之前不可缺少的工作是检查camera下的res文件夹和当前gallery工程下的res文件夹下的文件有无重名。例如:两者的values文件夹下都有atrrs.xml文件,则需要将camera的那一份重命名为atrrs_camera.xml,否则会发生覆盖导致出错。此时,在Gallery工程里右击import-General-File System,展开下面的两格小窗,不要选.git、test、Android.mk、CleanSpec.mk文件夹。
e.点击Clean后,发现gen/com.android.gallery3d下已经生成了R.java,要注意的是,此时Camera工程原本自身的com.android.camera.R(指向其对应的资源)也都整合到com.android.gallery3d.R文件中了。因此凡是有import com.android.camera.R的地方都该换成import com.android.gallery3d.R来替换。同时,之前引用了R导致报错的地方也应该import com.android.gallery3d.R。
f.等两秒,发现红叉不见了,clean编译时会报错:ImageFilterSharpen.java函数里找不到forEach_root()函数。在源代码编译的输出文件路径/out/target/common/obj/APPS/GALLERY2_intermediates/src/com/android/Gallery3d/filtershow/filters文件夹下找到ScriptC_convolve3x3.java一共可以找到3份同名的文件,将有forEach_root(Allocation, Allocation)接口的文件拷贝一份出来,在com.android.gallery3d.filtershow.filters路径下,将其名字改为MyScriptC_convolve3x3.java,区别开gen路径下的ScriptC_convolve3x3.java。并在引用其构造实例的地方更改名字,如在ImageFilterSharpen.java中,将ScriptC_convolve3x3 mScript改为MyScriptC_convolve3x3 mScript,并在相应地方同步更改类名。MyScriptC_convolve3x3.java代码如下:
经过上述步骤,基于Android4.2源码的Gallery2、Camera模块在eclipse里面已能正常编译,生成对应的apk,贴一张“劫后照”:
二、apk安装
在Run As Android Application时, 接入真机后Console上会报错:Re-installation failed due to different application signatures。You must perform a full uninstall of the application. WARNING: This will remove the application data! Please execute 'adb uninstall com.android.gallery3d' in a shell.接着就退出了。但用模拟器运行则不会有错。从上面的错误信息中容易知道,这是因为现在的Android手机中很多已有了gallery3d系列应用,安装同名(我对应的版本号在AndroidManifest.xml下显示是1.1.40001)包会报冲突——有人就更改了包名,后面一路安装顺畅,最后在手机上出现了两个图库和相机应用。我没有这样做,选择的是删掉旧的应用包(系统默认包),安装新应用包。
查阅了一些文档,发现此方法简单有效——手机接入电脑,在windows下打开cmd,在adb.exe安装路径下使用adb shell进入手机真是系统级目录(区别于用户级目录),可以在/system/app下面看到Gallery.apk,使用rm命令删除之。再次回到eclipse里run项目的时候,依然会报Installation error: INSTALL_FAILED_UPDATE_INCOMPATIBLE错误。google一下,有人说是前一步删除旧的应用包时删的不太干净,因为/data/system/package.xml文件中或许还包含了该应用的相关信息,建议使用界面操作setting—>applications—>manage applications—>应用—> application Info —>uninstall进行优雅卸载。果然在我的手机setting下还能看到对应应用,于是我“强行停用”,并选择“清除数据”,“清除缓存”,重启了以后,再次clean,run,success!歪歪扭扭的图库+相机应用出现在了桌面上。(PS:刚开始相机有不明原因的卡顿,重启了两次手机后,ok了——目前不知晓原理,也许与系统launch之间需要一点点磨合?!)