【译】用资源切片来优化IOS应用大小

发表于2016-03-16
评论0 3.4k浏览

 原文地址:http://blogs.unity3d.com/2015/12/28/optimizing-ios-app-size-with-resource-slicing/

原文作者未做版权声明,视为共享知识产权进入公共领域,自动获得授权

 

 

应用切片(App Slicing)是自iOStvOS 9.0开始加入的一个iOS新特性,其目的是减小主应用程序包的大小。开发者将与多种设备相关的资源版本上传到App Store, 只有符合用户当前设备版本的资源才会包含在下载的应用包里。


应用切片(App Slicing)在iOS平台上非常有用,因为开发者可以将更多的资产(Asset)打包进初始的应用包内,而仍能保证不会超过100MB的下载大小限制。要达成这个目标,开发者也可以使用我们前面介绍过的按需加载资源(On-demand Resource)。但是,要使用按需加载资源,应用必须能够做到动态下载所需资源。但这并不是任何时候都合适或最优的,而且做起来也很复杂。应用切片则不存在这些缺点。


应用切片有两类:应用可执行程序切片以及应用资源切片。前者会移除应用程序包中无用的可执行代码。App Store对于所有iOS/tvOS 9.0及以上版本的应用会自动执行这一动作。后者会移除无用的资产。开发者需要做更多的工作来实现这个功能。这是我们将在这篇博文中将要介绍的内容。


资源切片的主要目标是解决数据冗余,相同资源的不同形式的使用是相对频繁的。因为不同新旧程度的iOS设备仍在广泛使用中,它们硬件版本间存在巨大的性能差异。开发者时常需要使用不同质量的资产,在充分挖掘高性能设备潜力的同时,也能照顾到其他低配的设备。在iOS 9.0之前,所有的资源变体都需要包含在主应用包中。这既浪费了设备空间,也浪费了带宽,因为最后只使用了所有资源变体中的一个。通过采取应用资源切片,应用程序包中的无用资产都能被排除在外。


有效利用应用资源切片的最佳途径是通过Asset Bundle。那是配合进行应用程序资产切片布局的最简单选择。Asset BundleUnity内置的,它的性能与加载普通数据文件的性能无异。Asset Bundle也被用作按需加载资源的后端,所以对一个已经使用了按需加载资源的应用添加应用瘦身(App Thinning)支持非常方便,反之亦然。当Asset Bundle配置完成后,你基本无需做额外修改就能使用应用资源切片。
要使用应用资源切片,开发者必须首先指定哪些设备要使用参与资源切片的所有资产变体,然后在应用程序启动时加载这些资产。在vanilla iOS应用开发中,需要先在资产目录里创建数据集或图像集,设置设备变体:
https://developer.apple.com/library/ios/recipes/xcode_help-image_catalog-1.0/chapters/CustomizingImageSets.html#//apple_ref/doc/uid/TP40013303-CH5-SW1


然后将资源指派给UI上的占位符。在Unity中,开发者需要设置资源包变体(即多个分别包含相同资产集,而资产集中的资产又互相不同的资源包)。在代码中使用UnityEditor.iOS.BuildPipeline.collectResources回调API注册所有要参与应用资源切片的资源包变体。然后,在Player Settings中指定确切的设备要求。最后,开发者需要在应用程序启动时使用AssetBundle.CreateFromFile API手动加载资源包。

 

下面两段代码示例演示了应用资源切片的要点:
注册要参与应用资源切片的资源的编辑器脚本:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
using UnityEditor.iOS;
#if ENABLE_IOS_APP_SLICING
public class BuildResources
{
 [InitializeOnLoadMethod]
 static void SetupResourcesBuild()
 {
   UnityEditor.iOS.BuildPipeline.collectResources += CollectResources;
 }
 static UnityEditor.iOS.Resource[] CollectResources()
 {
  return new Resource[] {
    new Resource("asset-bundle-name").BindVariant("path/to/asset-bundle.hd"), "hd")
                                     .BindVariant("path/to/asset-bundle.md"), "md")
                                     .BindVariant("path/to/asset-bundle.sd"), "sd"),
  };
 }


在启动时加载资源包:

< ...>var bundle = AssetBundle.LoadFromFile("res://asset-bundle-name");// now use AssetBundle APIs to load assets// or Application.LoadLevel to load scenesvar asset = bundle.LoadAsset("Asset");< ...>

 

开始探索资源包与应用资源切片的最简单方式就是阅读Asset Bundle Manager项目示例。以下链接提供了有关如何使用与微调Demo的详细介绍:
http://Unity3d.com/cn/learn/tutorials/topics/scripting/assetbundles-and-assetbundle-manager


如社区发表内容存在侵权行为,您可以点击这里查看侵权投诉指引