项目中要展示用户微信头像
类: AssetManager
方法loadRemote 使用 url 加载远程资源,例如音频,图片,文本等等。
1、自定义一个cache对象,用来存放 ImageAsset 和 SpriteFrame 的映射关系;
cache: { [name: string]: SpriteFrame } = {};
2、loadRemote 回调中,首先检查该 ImageAsset 是否已有对应的 SpriteFrame,有则直接用,没有则创建一个新的 SpriteFrame 和 Texture2D,然后计数加1;
assetManager.loadRemote<ImageAsset>(url, (err, imageAsset) => { if (!err && imageAsset) { let spFrame = this.cache[imageAsset._uuid]; if (!spFrame) { const texture = new Texture2D(); texture.image = imageAsset; spFrame = new SpriteFrame(); spFrame.texture = texture; imageAsset.addRef(); this.cache[imageAsset._uuid] = spFrame; // 添加映射表记录 } spFrame.addRef(); // 计数加1 } });
这样,对于N个相同资源,只会创建一份 ImageAsset、Texture2D 和 SpriteFrame,其中 SpriteFrame 的引用计数为N;
3、释放时,手动调用 SpriteFrame.decRef,然后判断引用计数,如果为0,则同时释放 ImageAsset 和 Texture2D,并从映射表里删除该 SpriteFrame 的记录。参考资料
releaseRemoteSprite(node: Node) { if (!isValid(node)) { return; } const sp = node.getComponent(Sprite) as Sprite; if (sp && sp.spriteFrame) { const spFrame = sp.spriteFrame; sp.spriteFrame.decRef(false); // 只把计数减1 sp.spriteFrame = null; if (spFrame.refCount <= 0) { let texture = spFrame.texture as Texture2D; // 如果已加入动态合图,必须取原始的Texture2D if (spFrame.packable) { texture = spFrame.original?._texture as Texture2D; } if (texture) { delete this.cache[texture.image!._uuid]; // 删除映射表记录 texture.image?.decRef(); texture.destroy(); } spFrame.destroy(); } } }
综合以上资料,由于我只需要微信头像,所以简单获取节点更新一下图片,暂不知道有什么影响
微信头像已下载至服务器本地
修改代码如下:
if(userInfo['head'] != ''){ let url = userInfo['head']; assetManager.loadRemote<ImageAsset>(url, (err, imageAsset) => { if (!err && imageAsset) { let spFrame = this.cache[imageAsset._uuid]; if (!spFrame) { const texture = new Texture2D(); texture.image = imageAsset; spFrame = new SpriteFrame(); spFrame.texture = texture; //节点路径 let head = cc.find('Canvas/index/ShowUser/set_bg/user_bg/head/SpriteSplash/Mask/Sprite') head.getComponent(cc.Sprite).spriteFrame = spFrame imageAsset.addRef(); this.cache[imageAsset._uuid] = spFrame; // 添加映射表记录 } spFrame.addRef(); // 计数加1 } }); }