修改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。

修改Android 4.2.2的原生Camera引出的java.lang.UnsatisfiedLinkError: Native method not found,及解决方法的更多相关文章

  1. 【我的Android进阶之旅】Android调用JNI出错 java.lang.UnsatisfiedLinkError: No implementation found for的解决方法

    错误描述 今天使用第三方的so库时候,调用JNI方法时出现了错误.报错如下所示: 11-01 16:39:20.979 4669-4669/com.netease.xtc.cloudmusic E/a ...

  2. Android 高德地图 java.lang.UnsatisfiedlinkError Native method not found: com.autonavi.amap.mapcore.MapCore.nativeNewInstance:(Ljava/lang/String;)

    在Android项目中引用高德地图,程序运行时出现上述问题,如果引用了Map3D的jar包,则需要在引入Jar文件的同时引入so文件,在高德地图的demo中,找到so文件: 然后将其复制到jniLib ...

  3. android native开发时:java.lang.UnsatisfiedLinkError: Native method not found的处理

    这个异常一般是由于JNI的链接器不能正常识别C++的函数名造成的.处理的方法是用exern "C" {},来包裹需要export的C++的native方法. 如果native的方法 ...

  4. 1、Android Studio集成极光推送(Jpush) 报错 java.lang.UnsatisfiedLinkError: cn.jpush.android.service.PushProtoco

    Android studio 集成极光推送(Jpush) (华为手机)报错, E/JPush: [JPushGlobal] Get sdk version fail![获取sdk版本失败!] W/Sy ...

  5. android 使用讯飞人脸识别api报错:java.lang.UnsatisfiedLinkError

    1.在做一个人脸识别的项目,使用的是讯飞的api,编辑器为AS2.0,运行时报如下错误: FATAL EXCEPTION: main                  Process: com.adm ...

  6. Android (二维码)关于java.lang.UnsatisfiedLinkError的小案例

    在许多项目中我们都会用到第三方动态库.so文件,但是往往会引来很多烦恼,比如:Java.lang.UnsatisfiedLinkError - ::-/com.ishow.scan E/Android ...

  7. Android学习问题记录之java.lang.UnsatisfiedLinkError

    1.问题描述 Android Studio引入第三方类库时,出现错误java.lang.UnsatisfiedLinkError: 11-09 14:58:05.500 13280-13280/cn. ...

  8. android 高德地图API 之 java.lang.UnsatisfiedLinkError: Couldn't load amapv3: findLibrary returned null错误

    错误场景: 运行android app时,在运行到调用高德地图API时,出现 “java.lang.UnsatisfiedLinkError: Couldn't load amapv3: findLi ...

  9. Android studio中找不到so文件的问题:java.lang.UnsatisfiedLinkError

    解决Android studio中找不到so文件的问题:java.lang.UnsatisfiedLinkError 表示我们不编译jni代码,直接从libs里面复制so库 文件路径:app\buil ...

随机推荐

  1. JS sort()实用技巧

    [1, 3, 9, 2].sort(); // Returns: [1, 2, 3, 9] // 返回 [1, 2, 3, 9]   --这没错,但它还有更强大的用法,比如这样: var data=[ ...

  2. oracle 10g函数大全--分析函数

    oracle分析函数--SQL*PLUS环境 一.总体介绍 12.1 分析函数如何工作 语法 FUNCTION_NAME(<参数>,…) OVER (<PARTITION BY 表达 ...

  3. STL front() ,back()和begin(),end()区别

    首先看看vector里面的: reference front(); const_reference front() const; queue里面的: value_type& front(); ...

  4. Hdu 3371 Connect the Cities(最小生成树)

    地址:http://acm.hdu.edu.cn/showproblem.php?pid=3371 其实就是最小生成树,但是这其中有值得注意的地方:就是重边.题目没有告诉你两个城市之间只有一条路可走, ...

  5. Poj 2499 Binary Tree(贪心)

    题目链接:http://poj.org/problem?id=2499 思路分析:结点向左边移动时结点(a, b)变为( a+b, b),向右边移动时( a, b )变为( a, a + b); 为求 ...

  6. leetcode先刷_Search in Rotated Sorted Array II

    上一页下一页,找到相同的旋转阵列的问题.假设数组元素一再怎么办呢?会发生什么? 我给大家举一个极端的例子.如果是这样的阵列中的元件.1,1,2,1,1,1,1,我们想看看这个数组2,刚开始A[midd ...

  7. ceph存储之查找对象

    对象存储(而非块存储): 要把对象存入ceph集群,客户端必须做到: 1.指定对象名 2.指定存储池 Ceph客户端检出最新集群运行图,客户端用CRUSH算法动态地计算出如何把对象映射到归置组.然后计 ...

  8. gpexpand error:Do not have enough valid segments to start the array.

    gpstart error: Do not have enough valid segments to start the array. 这个时候需要检查一下shared_buffers设置改小点,就 ...

  9. C语言结构体变量内存分配与地址对齐

    地址对齐简单来说就是为了提高访问内存的速度. 数组的地址分配比较简单,由于数据类型相同,地址对齐是一件自然而然的事情. 结构体由于存在不同基本数据类型的组合,所以地址对齐存在不同情况,但总体来说有以下 ...

  10. ContentType

    常用的 ContentType XML <% response.ContentType ="text/xml" %>  GIF images <% respons ...