文章目录

  • 一、 图片质量压缩方法
  • 二、 查找对应的 Native 方法源码
  • 三、 分析 Bitmap.cpp 中动态注册 Native 方法

在博客 【Android 内存优化】图片文件压缩 ( Android 原生 API 提供的图片压缩功能能 | 图片质量压缩 | 图片尺寸压缩 ) 简要介绍了 图片文件压缩格式 , 以及 Android 提供的图片质量 , 尺寸压缩原生 API ;

在博客 【Android 内存优化】Android 原生 API 图片压缩代码示例 ( PNG 格式压缩 | JPEG 格式压缩 | WEBP 格式压缩 | 动态权限申请 | Android10 存储策略 ) 主要使用了上述 Android 原生 API 压缩图片功能进行图片压缩 ;

本博客中将分析 Android 底层源码 , 具体分析图片压缩的原理 ;

先找到源码位置 ;

一、 图片质量压缩方法


在 【Android 内存优化】图片文件压缩 ( Android 原生 API 提供的图片压缩功能能 | 图片质量压缩 | 图片尺寸压缩 ) 三、 Android 原生 API 提供的质量压缩 章节对图片质量压缩方法中的代码进行了简要介绍 , 最终调用的方法是 nativeCompress 方法 , 执行实际的图片压缩逻辑 ;

// 执行 Native 方法, 压缩图片
boolean result = nativeCompress(mNativePtr, format.nativeInt,quality, stream, new byte[WORKING_COMPRESS_STORAGE]);

调用的 native 方法 : 查找其在 C++ 代码的对应函数 , 该 Native 函数定义在 Bitmap.cpp 中 ;

    private static native boolean nativeCompress(long nativeBitmap, int format,int quality, OutputStream stream,byte[] tempStorage);

源码位置 frameworks\base\graphics\java\android\graphics\Bitmap.java , 也可以直接在开发环境中查看该源码 ;

下面开始查找 nativeCompress 方法 , 分析其中的代码 ;

二、 查找对应的 Native 方法源码


1. Native 方法源码查找方法 :

① 文件名相同 : 一般情况下 Java 源码中的 Java 类的类名与对应的定义 Native 方法的 C++ 源码文件名称相同 ;

② 源码搜索 : 如果找不到 , 还是在 Source Insight 中查找对应的 native 方法 , 即可找到对应的 C++ 源码 ; 参考 【Android 系统开发】使用 Source InSight 阅读 Android 源码 博客 ;


上图是在 Source Insight 中查找 nativeCompress 关键字 , 就可以找到对应的 Bitmap.cpp 源码 ;

2 . 对应构建脚本分析 : 在 Android 源码的 frameworks\base\core\jni 目录下 , 定义了 Bitmap.cpp 编译成动态库的构建脚本 Android.mk , 该构建脚本配置编译了 libandroid_runtime 动态库 , 其中就包含了 Bitmap.cpp , Bitmap.java 中定义的 native 方法的具体实现就在该 frameworks\base\core\jni\android\graphics\Bitmap.cpp 中 ;

LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)# ... LOCAL_SRC_FILES:= \# ... android/graphics/Bitmap.cpp \android/graphics/BitmapFactory.cpp \#  ...LOCAL_C_INCLUDES += \$(JNI_H_INCLUDE) \#  ... LOCAL_SHARED_LIBRARIES := \libmemtrack #  ...LOCAL_MODULE:= libandroid_runtimeinclude external/stlport/libstlport.mk
include $(BUILD_SHARED_LIBRARY)include $(call all-makefiles-under,$(LOCAL_PATH))

该构建脚本的源码位置 \frameworks\base\core\jni\Android.mk

三、 分析 Bitmap.cpp 中动态注册 Native 方法


参考博客 【Android NDK 开发】JNI 动态注册 ( 动态注册流程 | JNI_OnLoad 方法 | JNINativeMethod 结构体 | GetEnv | RegisterNatives ) 内容 , 在该博客中详细介绍了动态注册的详细细节 ;

Bitmap.java 中的 nativeCompress 方法 使用的是动态注册的方式 与 Bitmap.cpp 中的 Bitmap_compress 方法对应 ;

1. 动态注册流程 :

① 定义 JNINativeMethod 结构体 : 首先定义了 JNINativeMethod 结构体 , 该结构体由三个成员 , Java 函数名 , java 函数签名 , C++ 函数签名 ;

        typedef struct {const char* name;       //Java 中定义的 Native 方法名 , 注意这是一个 C 字符串const char* signature;  //函数签名 , 可以使用 javap 生成void*       fnPtr;      //C/C++ 中的 Native 函数签名} JNINativeMethod;

② 获取 Java 类 : 获取要注册的 Java 类名称 ;

③ 批量注册 : 最终要调用 JNIEnv 的 RegisterNatives 方法 , 批量注册代码 ; 下面代码中的 android::AndroidRuntime::registerNativeMethods 方法定义在 frameworks\base\core\jni\AndroidRuntime.cpp 中 , 在该方法中又调用了 libnativehelper\JNIHelp.cpp 中的 jniRegisterNativeMethods 方法 , 在该方法中调用了 JNIEnv 的 RegisterNatives 方法注册了这一批 Bitmap.java 的函数 ;

2. Bitmap.cpp 中完整动态注册代码 : 其中对关键代码进行了注释 ;

// 调用的 register_android_graphics_Bitmap 注册函数方法定义在该头文件中
#include <android_runtime/AndroidRuntime.h>// 定义了 JNINativeMethod 结构体数组
static JNINativeMethod gBitmapMethods[] = {{   "nativeCreate",             "([IIIIIIZ)Landroid/graphics/Bitmap;",(void*)Bitmap_creator },{   "nativeCopy",               "(JIZ)Landroid/graphics/Bitmap;",(void*)Bitmap_copy },{   "nativeDestructor",         "(J)V", (void*)Bitmap_destructor },{   "nativeRecycle",            "(J)Z", (void*)Bitmap_recycle },{   "nativeReconfigure",        "(JIIIIZ)V", (void*)Bitmap_reconfigure },// nativeCompress 图片压缩方法// Java 中的方法名是 nativeCompress // Java 中的方法签名 (JIILjava/io/OutputStream;[B)Z// C++ 中的方法签名 (void*)Bitmap_compress{   "nativeCompress",           "(JIILjava/io/OutputStream;[B)Z",(void*)Bitmap_compress },{   "nativeErase",              "(JI)V", (void*)Bitmap_erase },{   "nativeRowBytes",           "(J)I", (void*)Bitmap_rowBytes },{   "nativeConfig",             "(J)I", (void*)Bitmap_config },{   "nativeHasAlpha",           "(J)Z", (void*)Bitmap_hasAlpha },{   "nativeIsPremultiplied",    "(J)Z", (void*)Bitmap_isPremultiplied},{   "nativeSetHasAlpha",        "(JZZ)V", (void*)Bitmap_setHasAlpha},{   "nativeSetPremultiplied",   "(JZ)V", (void*)Bitmap_setPremultiplied},{   "nativeHasMipMap",          "(J)Z", (void*)Bitmap_hasMipMap },{   "nativeSetHasMipMap",       "(JZ)V", (void*)Bitmap_setHasMipMap },{   "nativeCreateFromParcel","(Landroid/os/Parcel;)Landroid/graphics/Bitmap;",(void*)Bitmap_createFromParcel },{   "nativeWriteToParcel",      "(JZILandroid/os/Parcel;)Z",(void*)Bitmap_writeToParcel },{   "nativeExtractAlpha",       "(JJ[I)Landroid/graphics/Bitmap;",(void*)Bitmap_extractAlpha },{   "nativeGenerationId",       "(J)I", (void*)Bitmap_getGenerationId },{   "nativeGetPixel",           "(JII)I", (void*)Bitmap_getPixel },{   "nativeGetPixels",          "(J[IIIIIII)V", (void*)Bitmap_getPixels },{   "nativeSetPixel",           "(JIII)V", (void*)Bitmap_setPixel },{   "nativeSetPixels",          "(J[IIIIIII)V", (void*)Bitmap_setPixels },{   "nativeCopyPixelsToBuffer", "(JLjava/nio/Buffer;)V",(void*)Bitmap_copyPixelsToBuffer },{   "nativeCopyPixelsFromBuffer", "(JLjava/nio/Buffer;)V",(void*)Bitmap_copyPixelsFromBuffer },{   "nativeSameAs",             "(JJ)Z", (void*)Bitmap_sameAs },{   "nativePrepareToDraw",      "(J)V", (void*)Bitmap_prepareToDraw },
};#define kClassPathName  "android/graphics/Bitmap"// 动态注册函数的实际方法
int register_android_graphics_Bitmap(JNIEnv* env)
{// 该方法最终调用了 libnativehelper\JNIHelp.cpp 中的  jniRegisterNativeMethods 方法return android::AndroidRuntime::registerNativeMethods(env, kClassPathName,gBitmapMethods, SK_ARRAY_COUNT(gBitmapMethods));
}

源码位置 \frameworks\base\core\jni\android\graphics\Bitmap.cpp

【Android 内存优化】Android 原生 API 图片压缩原理 ( 图片质量压缩方法 | 查找 Java 源码中的 native 方法对应的 C++ 源码 )相关推荐

  1. Android内存优化—Android的内存管理方式

    内存管理机制 从操作系统的角度来说,内存就是一块数据存储区域,属于可被操作系统调度的资源.现代多任务(进程)的操作系统中,内存管理尤为重要,操作系统需要为每一个进程合理的分配内存资源,所以可以从两方面 ...

  2. 【Android 内存优化】Android 原生 API 图片压缩原理 ( 哈夫曼编码开关 | 哈夫曼编码原理 | libjpeg-turbo 函数库 )

    文章目录 一. 哈夫曼编码开关 二. 哈夫曼编码原理 三. libjpeg-turbo 函数库 四. libjpeg-turbo 函数库下载 [Android 内存优化]图片文件压缩 ( Androi ...

  3. 【Android 内存优化】Android 原生 API 图片压缩原理 ( Bitmap_compress 方法解析 | Skia 二维图形库 | libjpeg 函数库 | libpng 函数库 )

    文章目录 一. 图片质量压缩方法 二. Skia 二维图形库 三. libjpeg.libpng 函数库引入 在博客 [Android 内存优化]图片文件压缩 ( Android 原生 API 提供的 ...

  4. 【Android 内存优化】Bitmap 图像尺寸缩小 ( 考虑像素密度、针对从不同像素密度资源中解码对应的 Bitmap 对象 | inDensity | inTargetDensity )

    文章目录 一.像素密度对解码图片的影响 二.不考虑像素密度会导致图片缩小尺寸不准确 三.DisplayMetrics 源码阅读.研究手机资源获取规则 四.像素密度参数设置取值 ( inDensity ...

  5. 【Android 内存优化】Android 原生 API 图片压缩代码示例 ( PNG 格式压缩 | JPEG 格式压缩 | WEBP 格式压缩 | 动态权限申请 | Android10 存储策略 )

    文章目录 一. 图片质量压缩 二. 图片尺寸压缩 三. Android 10 文件访问 四. 完整源码示例 上一篇博客 [Android 内存优化]图片文件压缩 ( Android 原生 API 提供 ...

  6. 【Android 内存优化】Android 工程中使用 libjpeg-turbo 压缩图片 ( 初始化压缩对象 | 打开文件 | 设置压缩参数 | 写入压缩图像数据 | 完成压缩 | 释放资源 )

    文章目录 一.使用 libjpeg-turbo 压缩图片流程 二.初始化 JPEG 压缩对象 三.打开文件 四.设置压缩参数 五.开始压缩 六.循环写入压缩数据 七.完成图片压缩及收尾 八.libjp ...

  7. 【Android 内存优化】Android 工程中使用 libjpeg-turbo 压缩图片 ( JNI 传递 Bitmap | 获取位图信息 | 获取图像数据 | 图像数据过滤 | 释放资源 )

    文章目录 一.Bitmap 图像数据处理 二.Java 层 Bitmap 对象转为 JNI 层 bitmap 对象 三.获取 bitmap 中的图像数据 四.过滤 bitmap 中的图像数据 ( 获取 ...

  8. 【Android 内存优化】Bitmap 硬盘缓存 ( Google 官方 Bitmap 示例 | DiskLruCache 开源库 | 代码示例 )

    文章目录 一.Google 官方 Bitmap 相关示例参考 二.磁盘缓存类 DiskLruCache 三.磁盘缓存初始化 四.存储数据到磁盘缓存中 五.从磁盘缓存中读取数据 六. Android 1 ...

  9. 【Android 内存优化】libjpeg-turbo 函数库交叉编译 ( libjpeg-turbo 函数库下载 | libjpeg-turbo 编译文档 | 环境准备 | NASM 安装 )

    文章目录 一. libjpeg-turbo 函数库下载与解压 二. libjpeg-turbo 编译文档 三. 编译前环境准备 四. 安装 NASM 汇编工具 1. 下载 NASM 汇编工具 2. 拷 ...

最新文章

  1. 力扣(LeetCode)刷题,简单题(第10期)
  2. db2联邦数据库 linux,DB2创建联邦数据库
  3. 万全服务器t350装系统_计算机中那些事儿(八):再历装系统之终身学习
  4. win32线程学习总结(临界区,互斥体,事件,信号量)
  5. Lucene搜索引擎例子demo
  6. 文本挖掘(part7)--Word2vec
  7. 尝试使用jBPM Console NG(测试版)
  8. 汇编语言和C语言单片机哪个更好用?
  9. 阿里云服务器连接ftp服务(软件的使用)
  10. 信息系统安全等级保护 备案表
  11. JAVA自学-day16-List的子类、泛型、增强for循环、静态导入、可变参数
  12. JEECG集成flowable
  13. 给toB创业程序员的建议
  14. Catia 滚动轴承设计
  15. IDC评述网:11月份海外域名主机服务商TOP10
  16. 我国已建立30个5G基站 仪表厂商发力5G第二阶段测试
  17. 西普实验吧CTF-约瑟夫环
  18. Python异步爬虫技术:10秒抓取3000条房源信息!
  19. cuug内部oracle视频教程-oracle sql_tune
  20. Python环境搭建—安利Python小白的Python和Pycharm安装详细教程

热门文章

  1. SQL注入不能多句执行时的一种突破方法(SA权限)
  2. linux每天进步一点点-7月3日
  3. 【作业四】软件案例分析之必应词典
  4. undefined reference to 'pthread_mutex_trylock'
  5. 算法学习:后缀数组 height的求取
  6. P4161 [SCOI2009]游戏
  7. 排序_简单排序_选择排序
  8. MongoDB在windows服务器安装部署及远程连接MongoDB
  9. Python之路【第一篇】:Python简介和入门
  10. c# 字符串排序 (面试题)