返回

Delphi移动资源管理:双重存储机制详解与优化

IOS

Delphi移动项目:资源在二进制文件与资源目录的双重存储

Delphi 移动开发中,常会遇到一种情况,添加到“项目 > 资源与图片”中的 PNG 图片等资源,既会嵌入到最终的二进制文件中,也会以单独文件的形式出现在 Android 的 Assets 目录以及 iOS 的 StartUp/Documents 目录下。这种资源的双重存储方式让人困惑,到底为何要如此处理?

双重存储的原因

这种现象并非 Delphi 特有的问题,而是与移动平台的特性和开发需求密切相关。其核心原因可以归结为两点:

  • 不同场景的需求 : 资源嵌入二进制文件,目的是为了让应用在没有外部资源文件时仍可以正常运行,例如一些关键的界面元素、图标等等。这些资源随应用启动加载,读取速度快。而独立的资源文件则提供了灵活性,允许程序运行时动态访问资源,方便更新资源包,减少应用安装包的整体大小。同时某些第三方组件或功能依赖于可独立访问的资源文件。
  • 移动平台的限制 : 移动平台对应用资源的处理方式有一定约束。有些资源,比如较大尺寸的图像或音频,通常不适合直接嵌入到二进制中。使用独立的资源文件能更好地管理这些资源,也符合移动操作系统的资源管理策略。

这种双重机制是一种折衷方案,既保证了应用的完整性,又兼顾了灵活性与效率。

资源管理最佳实践

在资源管理方面,嵌入二进制与存储为单独文件各有优劣。

嵌入二进制文件的优点

  • 减少依赖 : 应用运行时无需额外寻找资源文件,降低了资源加载失败的风险。
  • 加载速度快 : 内嵌资源直接加载,效率高。

嵌入二进制文件的缺点

  • 增加安装包大小 : 所有嵌入资源都会增大安装包体积。
  • 更新困难 : 修改嵌入资源,必须重新编译发布应用。

存储为独立文件的优点

  • 减少安装包大小 : 将较大资源放入单独文件,缩小安装包体积。
  • 更新灵活 : 可以更新单独资源文件,而无需重新发布应用(仅限更新应用可修改的路径)。

存储为独立文件的缺点

  • 依赖资源目录 : 需要管理资源路径。
  • 加载速度稍慢 : 读取独立资源文件比加载嵌入资源稍慢。

建议方案

为实现最佳性能,可以按需采取策略:

  • 优先嵌入 : 将应用程序中必须使用的小型图像,图标、字符串等小型资源嵌入二进制文件。
  • 使用独立资源文件 : 对于大型图片、视频、音频等体积较大的资源以及需要动态修改或更新的资源,将其存储为独立文件是更佳的选择。

对于图像,推荐在 Delphi 中选择适当的图像格式和压缩算法,以进一步优化文件大小。在确保图片质量的情况下尽量降低资源体积。

资源管理的优化技巧

除了上述策略外,还可以在项目中采用以下技巧:

  1. 删除重复资源

    项目经常会因为一些复制操作导致资源文件在各个路径存在多份副本。可以通过手动检查或者使用文件比对工具,找到这些重复的资源文件,确保只有一个版本。使用文本编辑器打开 .dproj 项目文件,并清理其中重复的<ItemGroup> 节点定义。

    操作步骤:
    1. 使用文本编辑器 (例如 Notepad++ , Sublime Text ) 打开 .dproj 项目文件
    2. 查找包含 <ItemGroup><Image ...></Image> 或者类似结构的代码块
    3. 确保对于同一个资源(例如 a.png)只有唯一的一个条目
    4. 保存 .dproj 项目文件
    5. 在 IDE 中重新加载项目

  2. 利用 AssetsDocuments 目录进行外部资源访问

    对于独立资源文件,Delphi提供了标准方式在代码中通过相对路径或平台相关API直接进行访问。

    • 访问 Assets目录 (Android): TPath.Combine(TPath.GetDocumentsPath, 'YourAsset.png') 或是平台相关的JNI.FindClass方法访问AssetManager 获取Stream
    • 访问 StartUp/Documents目录 (iOS):使用TPath.Combine(TPath.GetDocumentsPath, 'YourImage.png')直接读取.

    以下示例演示了如何通过文件路径访问图片:

    uses
      System.IOUtils, FMX.Graphics, FMX.Controls;
    
    procedure LoadImageFromFile(ImageControl: TImage; ImageFileName: string);
    var
        ImagePath: string;
        MyImage : TBitmap;
    begin
       ImagePath := TPath.Combine(TPath.GetDocumentsPath,ImageFileName );
       if TFile.Exists(ImagePath) then
         begin
            MyImage := TBitmap.Create;
            try
               MyImage.LoadFromFile(ImagePath);
               ImageControl.Bitmap := MyImage;
            finally
                MyImage.Free;
             end;
    
         end else
          begin
             //文件不存在时的处理逻辑
           end;
    end;
    
  3. 使用 Asset 包

    将特定类型的资源,例如 UI 使用的所有图片、动画,或者音频,放到一个独立于应用主体 APK 的资源包。在需要使用这些资源时动态加载资源包。这个策略对于大型应用是可选项。

结语

资源双重存储机制是为移动平台提供最佳应用性能和灵活更新而做出的权衡选择。理解其中原理,并在实际开发中灵活运用资源管理技巧,才能有效地优化应用,提升用户体验。