【问题标题】:Android assets are too slowAndroid 资源太慢了
【发布时间】:2018-05-28 13:08:06
【问题描述】:

我有带有资产的 Android 应用。它们包含 20,000 多个文件,其中大多数是简单的文本或 png 文件,它们被分成不同的文件夹和子文件夹。 1个单个文件最大500kb,90%在2kb左右。

示例结构

Data
  ... subfolders with 20k+ files
StartData
  .... FolderA
  ........ 5 files *.txt
  .... FolderB 
  ........ 5 files *.txt
  .... a.xml
  .... b.xml

问题是应用程序的加载时间。在应用加载期间,我需要从StartData 目录中打开大约 20 个文件并从中读取设置。它们位于 2 个 xml 文件中,根据 xml 中的信息,我从两个子文件夹 FolderA / FoldeB 打开附加数据。

但是,速度很差,应用启动时间至少是没有资产的 3-4 倍。

在以前的版本中,我在 raw 目录中有 zip,它在第一次运行到文档目录时被解压缩。第一次运行很慢,但其他运行很快。这个解决方案的问题是安装速度太快,因为在旧手机上进行解压缩最多需要 5 分钟,并且在此过程中它不会死机。如果是这样,则应用程序已损坏并且数据仅部分解压缩,因此我放弃了此解决方案。

使用我以前的方法,如果解压缩正确完成,冷应用启动大约需要 5 秒。现在,有了资产,最多需要 20 秒。有什么解决办法吗?

我在 gradle 中禁用了资产压缩(我只有 *.txt、*.png 和 *.xml 文件)

aaptOptions{
       ignoreAssetsPattern  ''
       noCompress 'txt', 'png', 'xml'
       cruncherEnabled = false
}

但进步很小。

另外,我正在使用 NDK (JNI) 和 AssetManager 在 C++ 中加载我的资产。在 C++ 中打开资产的解决方案取自:http://www.50ply.com/blog/2013/01/19/loading-compressed-android-assets-with-file-pointer/

【问题讨论】:

  • 这20.000是否影响速度?如果您在资产中仅使用 10 个文件进行测试,那么加载时间是多少?
  • @greenapps 好像不是。

标签: android c++ android-ndk


【解决方案1】:

发现资产文件夹中数千个文件的偏移量很慢,我并不感到惊讶,而且文件系统更适合此类任务。我会说也许应该重写数据结构。例如,您可以将此信息放入数据库中。

我对 funopen() 技巧持怀疑态度。我的意思是,它工作可靠,但我担心开销。处理非压缩资产的更有效方法是通过AAsset_getBuffer()AAsset_openFileDescriptor()。检查使用文件描述符的example。请注意,最后,您的所有数千个“文件”都会有一个文件描述符。

顺便说一句,我不认为使用这些直接访问方法的 Java 性能比 C 差。您可以使用 zlib 从 APK 文件(ZIP 格式)中读取您的资产本身),但我怀疑你会比 AssetManager 更快。

【讨论】:

  • funopen 技巧是否意味着您丢失了从AAsset_getBuffer() 获得的“内存映射”? IE。需要为简单的读取分配和释放缓冲区。
  • @l33t:我相信使用 funopen() 技巧可以像使用 @987654324 一样有效地将未压缩的资产提供给 ffmpeg @。但是这种方法失去了通过AAsset_getBuffer() 获得的内存映射。我不确定缓冲区分配有多糟糕,但如果您可以使用 AAsset_GetBuffer() 代替,即使 memcpy() 也是浪费。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-07-22
  • 2019-04-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多