Android4.2中Gallery2源码移植

最近开始做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.jarframework_intermediates.jarmp4parser_intermediates.jarxmp_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.xmlphotoeditor_strings.xmlstrings.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代码如下:


  1. /* 
  2.  * Copyright (C) 2011-2012 The Android Open Source Project 
  3.  * 
  4.  * Licensed under the Apache License, Version 2.0 (the "License"); 
  5.  * you may not use this file except in compliance with the License. 
  6.  * You may obtain a copy of the License at 
  7.  * 
  8.  *      http://www.apache.org/licenses/LICENSE-2.0 
  9.  * 
  10.  * Unless required by applicable law or agreed to in writing, software 
  11.  * distributed under the License is distributed on an "AS IS" BASIS, 
  12.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
  13.  * See the License for the specific language governing permissions and 
  14.  * limitations under the License. 
  15.  */  
  16.    
  17. package com.android.gallery3d.filtershow.filters;  
  18.   
  19. import android.renderscript.*;  
  20. import android.content.res.Resources;  
  21.   
  22. /** 
  23.  * @hide 
  24.  */  
  25. public class MyScriptC_convolve3x3 extends ScriptC {  
  26.     private static final String __rs_resource_name = "convolve3x3";  
  27.     // Constructor  
  28.     public  MyScriptC_convolve3x3(RenderScript rs) {  
  29.         this(rs,  
  30.              rs.getApplicationContext().getResources(),  
  31.              rs.getApplicationContext().getResources().getIdentifier(  
  32.                  __rs_resource_name, "raw",  
  33.                  rs.getApplicationContext().getPackageName()));  
  34.     }  
  35.   
  36.     public  MyScriptC_convolve3x3(RenderScript rs, Resources resources, int id) {  
  37.         super(rs, resources, id);  
  38.         __I32 = Element.I32(rs);  
  39.         __ALLOCATION = Element.ALLOCATION(rs);  
  40.         __F32 = Element.F32(rs);  
  41.         __U8_4 = Element.U8_4(rs);  
  42.     }  
  43.   
  44.     private Element __ALLOCATION;  
  45.     private Element __F32;  
  46.     private Element __I32;  
  47.     private Element __U8_4;  
  48.     private FieldPacker __rs_fp_ALLOCATION;  
  49.     private FieldPacker __rs_fp_F32;  
  50.     private FieldPacker __rs_fp_I32;  
  51.     private final static int mExportVarIdx_gWidth = 0;  
  52.     private int mExportVar_gWidth;  
  53.     public synchronized void set_gWidth(int v) {  
  54.         setVar(mExportVarIdx_gWidth, v);  
  55.         mExportVar_gWidth = v;  
  56.     }  
  57.   
  58.     public int get_gWidth() {  
  59.         return mExportVar_gWidth;  
  60.     }  
  61.   
  62.     public Script.FieldID getFieldID_gWidth() {  
  63.         return createFieldID(mExportVarIdx_gWidth, null);  
  64.     }  
  65.   
  66.     private final static int mExportVarIdx_gHeight = 1;  
  67.     private int mExportVar_gHeight;  
  68.     public synchronized void set_gHeight(int v) {  
  69.         setVar(mExportVarIdx_gHeight, v);  
  70.         mExportVar_gHeight = v;  
  71.     }  
  72.   
  73.     public int get_gHeight() {  
  74.         return mExportVar_gHeight;  
  75.     }  
  76.   
  77.     public Script.FieldID getFieldID_gHeight() {  
  78.         return createFieldID(mExportVarIdx_gHeight, null);  
  79.     }  
  80.   
  81.     private final static int mExportVarIdx_gPixels = 2;  
  82.     private Allocation mExportVar_gPixels;  
  83.     public void bind_gPixels(Allocation v) {  
  84.         mExportVar_gPixels = v;  
  85.         if (v == null) bindAllocation(null, mExportVarIdx_gPixels);  
  86.         else bindAllocation(v, mExportVarIdx_gPixels);  
  87.     }  
  88.   
  89.     public Allocation get_gPixels() {  
  90.         return mExportVar_gPixels;  
  91.     }  
  92.   
  93.     private final static int mExportVarIdx_gIn = 3;  
  94.     private Allocation mExportVar_gIn;  
  95.     public synchronized void set_gIn(Allocation v) {  
  96.         setVar(mExportVarIdx_gIn, v);  
  97.         mExportVar_gIn = v;  
  98.     }  
  99.   
  100.     public Allocation get_gIn() {  
  101.         return mExportVar_gIn;  
  102.     }  
  103.   
  104.     public Script.FieldID getFieldID_gIn() {  
  105.         return createFieldID(mExportVarIdx_gIn, null);  
  106.     }  
  107.   
  108.     private final static int mExportVarIdx_gCoeffs = 4;  
  109.     private float[] mExportVar_gCoeffs;  
  110.     public synchronized void set_gCoeffs(float[] v) {  
  111.         mExportVar_gCoeffs = v;  
  112.         FieldPacker fp = new FieldPacker(36);  
  113.         for (int ct1 = 0; ct1 < 9; ct1++) {  
  114.             fp.addF32(v[ct1]);  
  115.         }  
  116.   
  117.         int []__dimArr = new int[1];  
  118.         __dimArr[0] = 9;  
  119.         setVar(mExportVarIdx_gCoeffs, fp, __F32, __dimArr);  
  120.     }  
  121.   
  122.     public float[] get_gCoeffs() {  
  123.         return mExportVar_gCoeffs;  
  124.     }  
  125.   
  126.     public Script.FieldID getFieldID_gCoeffs() {  
  127.         return createFieldID(mExportVarIdx_gCoeffs, null);  
  128.     }  
  129.   
  130.     private final static int mExportForEachIdx_root = 0;  
  131.     public Script.KernelID getKernelID_root() {  
  132.         return createKernelID(mExportForEachIdx_root, 3nullnull);  
  133.     }  
  134.   
  135.     public void forEach_root(Allocation ain, Allocation aout) {  
  136.         // check ain  
  137.         if (!ain.getType().getElement().isCompatible(__U8_4)) {  
  138.             throw new RSRuntimeException("Type mismatch with U8_4!");  
  139.         }  
  140.         // check aout  
  141.         if (!aout.getType().getElement().isCompatible(__U8_4)) {  
  142.             throw new RSRuntimeException("Type mismatch with U8_4!");  
  143.         }  
  144.         // Verify dimensions  
  145.         Type tIn = ain.getType();  
  146.         Type tOut = aout.getType();  
  147.         if ((tIn.getCount() != tOut.getCount()) ||  
  148.             (tIn.getX() != tOut.getX()) ||  
  149.             (tIn.getY() != tOut.getY()) ||  
  150.             (tIn.getZ() != tOut.getZ()) ||  
  151.             (tIn.hasFaces() != tOut.hasFaces()) ||  
  152.             (tIn.hasMipmaps() != tOut.hasMipmaps())) {  
  153.             throw new RSRuntimeException("Dimension mismatch between input and output parameters!");  
  154.         }  
  155.         forEach(mExportForEachIdx_root, ain, aout, null);  
  156.     }  
  157.   
  158. }  

经过上述步骤,基于Android4.2源码的Gallery2Camera模块在eclipse里面已能正常编译,生成对应的apk,贴一张“劫后照”:

Android4.2中Gallery2源码移植_第1张图片


二、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之间需要一点点磨合?!)



你可能感兴趣的:(Android4.2中Gallery2源码移植)