Addressable(二):从远程下载

Local和Rmote区别

刚刚第一篇有讲到,点击分组标签,在Inspector可以看到AB包将会打到什么位置和从什么位置加载。本地的话,打包出来AB会在APK包里,远程的不会。从APK加载远程的会从服务器下载。

在这里插入图片描述

开启远程的:找到Addressable Asset Settings文件,Build&Load Paths选择Remote.
并且这里的Disable Catalog Update On Startup我们勾选上,主要是我们后面代码自己控制要更新那些文件。

远程的下载到本地后会进行缓存,以后就会每次先从缓存中读取。如果删除了缓存,又会从服务器中读取。
注意:如果Remote类型关闭了下图该选项,不会缓存到本地,而是每次都从服务器下载。
在这里插入图片描述

Can Change Post Release和Cannot Change Post区别

可以看到在上图的Content Update Restriction里面还有一个Update Restriction(更新限制)选项,可以选中以下两种:
Can Change Post Release:
后续更新资源的话全量更新(直接替换旧资源)
Cannot Change Post Release:
后续更新资源的话增量更新(不改变旧资源包,使用新资源包加载改变的内容)

这两种的区别可以在下面的更新AB包的步骤看出区别。

更新AB包

假如我们现在已经有一个APK包发出去了,AB包的类型既有Local,又有Remote;既有Can Chage又有Cannot Change类型。那么APK将会从那些地方加载这些AB包呢?前面已经说过Local将会打进APK里,那么会放在本地,Remote将会放在远程服务器,使用时候将会从远程服务器下载下来,并提供是否缓存选项。

那么现在更新AB包,我们将怎么做呢?

  1. 选择Tool-Check for Content Update Restrictions
    在这里插入图片描述

点击后会弹出对话框要求选择之前打包生成的.bin文件.然后会出现如下界面
在这里插入图片描述
注意:这里会将Asset有改变的,并且分组选项是Cannot Change Post Release的包(将要增量更新的包),选择出来,然后点击右下角的apply change,就会有一个新的分组ContentUpdate出现,这个分组的包将会打在Remote,然后放在服务器,就能更新原来不论在Local,还是Remote的Cannot Change包。

而Can Change的包将会直接生成新的Bundle,到时候旧的APK更新Catalog后,就能从新的Bundle里去读到资源。
在这里插入图片描述

  1. 选择Build-Clean Build,把旧的本地资源包清除,再把ServerData的服务器资源包清除,再选中Update a Previous Build,同样要选择之前打包生成的.bin文件,这时候就打成了新的AB包。
    在这里插入图片描述

加载AB包

这里直接上代码,先检查有哪些要更新的。

 private List<object> _updateKeys = new List<object>();
 
 private async void UpdateCatalog()
    {
        //初始化Addressable
        var init = Addressables.InitializeAsync();
        await init.Task;
        
        //开始连接服务器检查更新
        var handle = Addressables.CheckForCatalogUpdates(false);
        await handle.Task;
        Debug.Log("check catalog status " + handle.Status);
        if (handle.Status == AsyncOperationStatus.Succeeded)
        {
            List<string> catalogs = handle.Result;
            if (catalogs != null && catalogs.Count > 0)
            {
                foreach (var catalog in catalogs)
                {
                    Debug.Log("catalog  " + catalog);
                }
                Debug.Log("download catalog start ");
                var updateHandle = Addressables.UpdateCatalogs(catalogs, false);
                await updateHandle.Task;
                foreach (var item in updateHandle.Result)
                {
                    Debug.Log("catalog result " + item.LocatorId);
                    foreach (var key in item.Keys)
                    {
                        Debug.Log("catalog key " + key);
                    }
                    _updateKeys.AddRange(item.Keys);
                }
                Debug.Log("download catalog finish " + updateHandle.Status);
            }
            else
            {
                Debug.Log("dont need update catalogs");
            }
        }
        Addressables.Release(handle);
    }

然后下载新的AB包:

 public void DownLoad()
    {
        StartCoroutine(DownAssetImpl());
    }
    
    public IEnumerator DownAssetImpl()
    {
        var downloadsize = Addressables.GetDownloadSizeAsync(_updateKeys);
        yield return downloadsize;
        Debug.Log("start download size :" + downloadsize.Result);

        if (downloadsize.Result > 0)
        {
            var download = Addressables.DownloadDependenciesAsync(_updateKeys, Addressables.MergeMode.Union);
            yield return download;
            //await download.Task;
            Debug.Log("download result type " + download.Result.GetType());
            foreach (var item in download.Result as List<UnityEngine.ResourceManagement.ResourceProviders.IAssetBundleResource>)
            {
                var ab = item.GetAssetBundle();
                Debug.Log("ab name " + ab.name);
                foreach (var name in ab.GetAllAssetNames())
                {
                    Debug.Log("asset name " + name);
                }
            }
            Addressables.Release(download);
        }
        Addressables.Release(downloadsize);
    }

原来AB包在Remote的是都能正常更新的,原来Local的并且Cannot Change(能增量更新的)也在刚刚打包过程中可以看到新生成了ContentUpdate分组的,并且放在了Remote。能够进行更新。
只有Local的并且Can Chage的旧包无法更新,只有新包才能正常加载。

示例

新建了四个预制体,放在四个Group里面:
LocalStatic: 本地的,Cannot Change Post Release的
LocalNoStatic:本地的,Can Change Post Release的
RemoteStatic:远程的,Cannot Change Post Release的
RemoteStatic:远程的,Can Change Post Release的
在这里插入图片描述

打出AB来,可以看到本地的AB:
在这里插入图片描述

远程的AB:
这里会有一个catalog的hast和json文件
在这里插入图片描述

然后在ServerData里面直接放了一个NetBox2,启动这个应用程序我们就能直接在本机访问localhost.。在这里插入图片描述
这里为了方便,直接打出一个Window平台的应用程序,可以看到,四个Prefab都加载出来了。
在这里插入图片描述

为了证明Remote分组的是从服务器加载下载的,把NexBox2关闭掉,并清除缓存(第一次下载下来并缓存到本地)。发现Remote的Prefab无法加载出来。
在这里插入图片描述

更新AB:
这里我对四个Prefab的高度都缩小一般,然后按照上面的更新AB包的方法,更新一遍AB包。

然后对刚刚的旧包进行操作,先UpdateCatalog,再DownLoad AB.
再次加载四个Prefab:
在这里插入图片描述
可以看到四个Prefab都发生了改变,只有LocalNoStatic这种没有发生改变。在前面也解释了,Local类型的,Can Change Post Release的更新AB后,并没有生成在contentupdate组里,而旧的路径,变成了新的catalog里面的路径,所以这个Prefab就丢了。

local non static 的Group是无法被AA系统更新的,万一不小心改到了这个Group了,并且使用了Update a Previous Build,那客户端会莫名其妙无法加载资源,所以强烈反对使用这种Group.官方文档上也忽略了这种Group.

而如果打出新的包出来,四个Prefab都加载正常。
在这里插入图片描述

示例工程:
https://download.csdn.net/download/KindSuper_liu/81588390

参考:
https://blog.csdn.net/qq_14903317/article/details/108529590#comments_20052993

猜你喜欢

转载自blog.csdn.net/KindSuper_liu/article/details/123030402