修改Android 4.2.2的原生Camera应用,做一些定制,将Camera的包名从之前的 package com.android.* 修改成了com.zhao3546.*。

调整后,应用可以正常运行,但是Camera自带的特效编辑等功能,无法正常使用。一点图片编辑的图标,就出现了下面的异常:

09-12 18:52:48.131: E/AndroidRuntime(6071): java.lang.UnsatisfiedLinkError: Native method not found: com.zhao3546.gallery3d.filtershow.filters.ImageFilterFx.nativeApplyFilter:(Landroid/graphics/Bitmap;IILandroid/graphics/Bitmap;II)V
09-12 18:52:48.131: E/AndroidRuntime(6071): at com.zhao3546.gallery3d.filtershow.filters.ImageFilterFx.nativeApplyFilter(Native Method)
09-12 18:52:48.131: E/AndroidRuntime(6071): at com.zhao3546.gallery3d.filtershow.filters.ImageFilterFx.apply(ImageFilterFx.java:58)
09-12 18:52:48.131: E/AndroidRuntime(6071): at com.zhao3546.gallery3d.filtershow.presets.ImagePreset.apply(ImagePreset.java:291)
09-12 18:52:48.131: E/AndroidRuntime(6071): at com.zhao3546.gallery3d.filtershow.cache.DirectPresetCache.compute(DirectPresetCache.java:156)
09-12 18:52:48.131: E/AndroidRuntime(6071): at com.zhao3546.gallery3d.filtershow.cache.DelayedPresetCache.handleMessage(DelayedPresetCache.java:50)

原来,ImageFilterFx.nativeApplyFilter() 的这个方法是通过JNI实现的,想想也是,不使用JNI的话,使用Java实现图片编辑的特效,效率要低不少。

关于JNI的介绍,个人觉得写得最好的是《Android框架揭秘》这本书的 “第四章 JNI和NDK”,从示例出发,再将原理娓娓道来,很深入浅出。

言归正传,看看怎么解决吧。

如下是根据 nativeApplyFilter 关键字搜索,找到的结果如下,只保留一小部分:

---- nativeApplyFilter Matches (55 in 30 files) ----
Bw.c (jni\filters):void JNIFUNCF(ImageFilterBW, nativeApplyFilter, jobject bitmap, jint width, jint height)
Bw.c (jni\filters):void JNIFUNCF(ImageFilterBWRed, nativeApplyFilter, jobject bitmap, jint width, jint height)
Bw.c (jni\filters):void JNIFUNCF(ImageFilterBWGreen, nativeApplyFilter, jobject bitmap, jint width, jint height)
Bw.c (jni\filters):void JNIFUNCF(ImageFilterBWBlue, nativeApplyFilter, jobject bitmap, jint width, jint height)
Bwfilter.c (jni\filters):void JNIFUNCF(ImageFilterBwFilter, nativeApplyFilter, jobject bitmap, jint width, jint height, jint rw, jint gw, jint bw)
Contrast.c (jni\filters):void JNIFUNCF(ImageFilterContrast, nativeApplyFilter, jobject bitmap, jint width, jint height, jfloat bright)
Exposure.c (jni\filters):void JNIFUNCF(ImageFilterExposure, nativeApplyFilter, jobject bitmap, jint width, jint height, jfloat bright)
Fx.c (jni\filters):void JNIFUNCF(ImageFilterFx, nativeApplyFilter, jobject bitmap, jint width, jint height, jobject lutbitmap,jint lutwidth, jint lutheight )
Geometry.c (jni\filters):void JNIFUNCF(ImageFilterGeometry, nativeApplyFilterFlip, jobject src, jint srcWidth, jint srcHeight, jobject dst, jint dstWidth, jint dstHeight, jint flip) {
Geometry.c (jni\filters):void JNIFUNCF(ImageFilterGeometry, nativeApplyFilterRotate, jobject src, jint srcWidth, jint srcHeight, jobject dst, jint dstWidth, jint dstHeight, jint rotate) {
Geometry.c (jni\filters):void JNIFUNCF(ImageFilterGeometry, nativeApplyFilterCrop, jobject src, jint srcWidth, jint srcHeight, jobject dst, jint dstWidth, jint dstHeight, jint offsetWidth, jint offsetHeight) {
Geometry.c (jni\filters):void JNIFUNCF(ImageFilterGeometry, nativeApplyFilterStraighten, jobject src, jint srcWidth, jint srcHeight, jobject dst, jint dstWidth, jint dstHeight, jfloat straightenAngle) {
Hue.c (jni\filters):void JNIFUNCF(ImageFilterHue, nativeApplyFilter, jobject bitmap, jint width, jint height, jfloatArray matrix)
ImageFilterBW.java (src\com\android\gallery3d\filtershow\filters): native protected void nativeApplyFilter(Bitmap bitmap, int w, int h);
ImageFilterBW.java (src\com\android\gallery3d\filtershow\filters): nativeApplyFilter(bitmap, w, h);

Native方法的实现,肯定是在C或CPP中,直接看第一个结果吧:

void JNIFUNCF(ImageFilterBW, nativeApplyFilter, jobject bitmap, jint width, jint height)
{
...
}

JNIFUNCF这个函数名有点怪啊,怎么全是大写,C或C++中,全大写一般是都常量或宏,啥情况?

看看是怎么定义的,再根据JNIFUNCF搜索下,在filters.h中有定义:

#define JNIFUNCF(cls, name, vars...) Java_com_android_gallery3d_filtershow_filters_ ## cls ## _ ## name(JNIEnv* env, jobject obj, vars)

原来是个宏,这个宏是啥意思如果你不明白,需要了解一些C的基础,

此处将 “Java_com_android_gallery3d_filtershow_filters_” 和 cls 对应的实际值和 name 对应的实际值,拼接成一个字符串作为实际的方法名。

之前我们修改了Java的包名,但是 Java_com_android_gallery3d_filtershow_filters_ 这个没有修改,所以导致最终生成的方法与修改后Java实现的Native方法的符号匹配不上了,将 Java_com_android_gallery3d_filtershow_filters_ 修改成 Java_com_zhao3546_gallery3d_filtershow_filters_ ,再放到源码编译环境上重新生成相应的so,再重新生成APK测试,ok,问题解决。

了解JNI机制,才是解决此类问题的KEY。

最新文章

  1. MAC与windows下打开当前文件路径的命令行(终端)
  2. web安全——代理(nginx)
  3. 更改Magento的base url
  4. openssl rsa 加解密
  5. JasperReport报表开发(一)--原理介绍
  6. Android项目实战(四十五):Zxing二维码切换横屏扫描
  7. 010 Editor 8.0.1 之 逆向分析及注册机编写
  8. jquery学习总结1-12
  9. Thinkphp 视图模型
  10. redis乐观锁(适用于秒杀系统)
  11. 【Java】 大话数据结构(16) 排序算法(3) (堆排序)
  12. python resize
  13. aircrack-ng 破解无线网络
  14. Python科学计算库灬numpy
  15. C#Remoting
  16. scvmm2008 错误 2941 0x80072efe
  17. Java日期时间实用工具类
  18. Redis 的 fields 遇到的问题
  19. Unix系统编程()open,read,write和lseek的综合练习
  20. 编写高质量代码改善C#程序的157个建议——建议40:使用event关键字为委托施加保护

热门文章

  1. spring的定时执行代码 跑批
  2. C# 计算器 运算符和数字键的keys对照
  3. java学习之IO文件分割
  4. redhat6.3安装matlab运行时MCR7.8,初步测试ok
  5. SQL查询各阶段的统计信息
  6. 【数据库摘要】5_Sql_IN
  7. cocos2d-html5 简易 下拉表单 控件
  8. 数据库 isnull()、nvl()、ifnull() 使用
  9. windows desktop.ini
  10. C语言,单链表操作(增删改查)(version 0.1)