Quantcast
Channel: 英特尔开发人员专区文章
Viewing all articles
Browse latest Browse all 172

面向 Android* 应用的本地库压缩 SDK

$
0
0

下载 PDF 文档

简介

Android 应用一般使用 Java* 进行编写,因为其讲究的设计面向对象,而且 Android 软件开发套件 (Android SDK) 可在 Java 内提供跨平台功能。 但是有时,开发人员需要使用 Android 的本地接口,尤其如果内存管理和性能至关重要时。 Android 的本地接口通过原生开发套件 (NDK) 提供,可支持在 C/C++ 内进行本地开发。

Google 软件市场上有许多 NDK 应用。 为了降低数据包的尺寸,一些 ISV 发布了单独的 APK 而非 FAT APK (单独的 APK 包括一个 ARM* 或一个 x86 函数库,但是 FAT APK 包含两者)。 FAT APK 由于单个的 APK。 它们更便于最终用户访问,且库在应用更新过程中不会被覆盖。 因此,我们鼓励开发人员为 x86 Android 软件生态系统发布 FAT APK。 但是,开发人员如何降低大型 FAT APK 文件的尺寸呢?

Zip* 与 LZMA

为了解决 FAT APK 的尺寸问题,作者开发了一款本地库压缩 SDK。 其基本理念是使用 Lempel–Ziv–Markov chain algorithm (LZMA) (http://www.7-zip.org/sdk.html) 来压缩本地库。 Google 使用 Zip 来压缩全部内容,虽然 Zip 速度快,但是其压缩率低于 LZMA。 LZMA 尤其适合压缩本地库中的大型目录文件。 下图展示了使用 Zip 和 LZMA 进行压缩后文件尺寸的区别。

 

图 1: 一个文件在使用 Zip* 和 LZMA 压缩后的尺寸比较1

 

图 2: 多个文件(相同的 CPU 架构)在使用 Zip* 和 LZMA 压缩后的尺寸比较1

 

图 3: 多个文件(不同的 CPU 架构)在使用 Zip* 和 LZMA 压缩后的尺寸比较1

 

图 4: 三个相同的文件在使用 Zip* 和 LZMA 压缩后的尺寸比较1

从上面的四个图标中,我们可以得出,LZMA 能够减少文件之间的冗余。 在极端案例(三个相同的文件)中,LZMA 的压缩率高于 Zip。 该功能尤其适合压缩本地库。 一般而言,本地库使用相同的代码获取 “armeabi”、”armeabi-v7a”、”x86” 甚至 “mips” 库,对于 “armeabi-v7a” ,有 ARM NEON* 和非 NEON 代码。 由于有相同的源代码,这些库有冗余。 即使使用不同的架构,例如 libffmpeg_armv7_vfpv3.solibffmpeg_x86.so,一个是 ARMEABI,另一个是 x86,压缩率也为 40%,然而对于单个文件而言,压缩率仅为 20%。

本地库压缩 SDK

作者开发的本地库压缩 SDK 能够帮助应用开发人员整合 LZMA 本地库压缩以获取更小的文件。 此 SDK 的核心理念是按照如下方式将整个本地库压缩至 asserts文件夹。

此 SDK 中的 API 非常简单。 首次运行此应用时,代码可从“资产(asserts)”文件夹中加压整个本地库。

static boolean NewInstance(Context cont,Handler hdl,boolean showProgress)
static DecRawso GetInstance()
String GetPath(String libname)

我们建议应用开发人员在应用启动时修改源代码并添加 NewInstance,然后将 system.loadlibrary(***)更改为 system.load(DecRawso。 GetInstance ().GetPath(***)). 做出这些小改动后,APK 的尺寸将会更小,但是能够像以往一样运行。

如果开发人员能够确保从调用 NewInstance 到首次加载本地库之间有足够的延迟,他们需要调用 (NewInstance (cont,null,false)),但不包括 Handler。 或者,传递 Handler来接收 “decode end” 异步消息。

作者将此 SDK 整合到基于英特尔® 凌动™ Z2760 处理器的平板电脑(代号 Clover Trail)上的 MoboPlayer* 中。 当用户启动应用且出现闪屏时,代码将以异步方式调用 NewInstance 。 调用 NewInsance 对最终用户透明,因为解码在后台完成。 下图展示了压缩结果。

 

表 5: MoboPlayer* FAT APK 尺寸压缩1

本地库压缩 SDK 的增强功能

除了 LZMA 压缩以外,该 SDK 可提供其他功能,以支持开发人员在以下特性中加入 x86 本地库: 

  1. 云存储: ISV 能够将 x86 库存储到云服务器上,这些库可在安装后从服务器进行下载。 该操作在 x86 设备上可自动完成,且仅在连接 Wi-Fi* 时启用。
  2. 丢失库检测:如果 x86 库丢失,SDK 将自动重新提取 ARM 库。 ISV 可将 ARM 库复制到 x86 文件夹中以避免该问题,但是必须确保 ARM 和 x86 库之间没有交叉引用。
  3. 针对封装的 Java 工具: Java 封装工具可用于将正常的 APK 转换为使用 LZMA 压缩的 APK。 该工具支持 Windows*、Linux* 和 Mac* 系统。 您可以将它用作: ComPressApk.jar -a C:/my/test.APK -k c:/key *** ### alias, 如果 “-k” 丢失(也就是说,您可以调用 ComPressApk.jar -a C:/my/test.APK,Eclipse* 默认测试密钥将用于在此 APK 上签名。 该工具可集成至 ants构建脚本,以支持自动编译和发布。
  4. 过滤器: 借助 ConfigureFilter函数,您可以只抽取必要的库。 例如,输入 ConfigureFilter("libffmpeg", "libffmpeg_armv7_neon.so")表示只抽取以 “ libffmpeg” 开头的所有库中抽取 “libffmpeg_armv7_neon.so”。 这对于降低安装后尺寸非常有帮助。

结论

使用针对 Android 应用的本地库压缩 SDK 能够显著降低本地库包的尺寸,并使采用大型本地库的应用(一般情况下,这些应用时视频播放器、浏览器和 3D 游戏)受益。 关于来源和技术支持,请联系作者。

关于作者

Yuming Li (Yuming.li@intel.com) 是英特尔软件与服务事业部的一位软件应用工程师。 目前,他主要关注多媒体相关应用的支持和性能优化,尤其在 Android 移动平台上。

 

1结果根据内部英特尔® 分析预测得出,仅供参考。 任何系统硬件、软件的设计或配置的不同均可能影响实际性能。

 

 


Viewing all articles
Browse latest Browse all 172

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>