1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > 【Android 内存优化】Android 原生 API 图片压缩原理 ( 图片质量压缩方法 |

【Android 内存优化】Android 原生 API 图片压缩原理 ( 图片质量压缩方法 |

时间:2024-01-11 10:45:43

相关推荐

【Android 内存优化】Android 原生 API 图片压缩原理 ( 图片质量压缩方法 |

文章目录

一、 图片质量压缩方法二、 查找对应的 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.mkinclude $(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++ 源码 )

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。