Cocos Creator 解决热更新资源md5比较引发卡顿问题(一)

简介: Cocos Creator 解决热更新资源md5比较引发卡顿问题

大家在使用Cococ Creator提供的热更新 assetsManagers ,做md5校验的时候,一定会遇到卡顿的问题。

备注:文末有完整实现源码



原因是 Cococ Creator 官方提供的热更新校验回调是在ui线程进行,如下代码所示:



assetsManagers.setVerifyCallback(function (path, asset)) {
      let compressed = asset.compressed;
      let expectedMD5 = asset.md5;
      let relativePath = asset.path;
      let size = asset.size;
      if (compressed) {
         cc.log(`Verification passed : ${relativePath}`);
         .... 
         return true;
      }
      else {
          cc.log(`Verification passed : ${relativePath} ( ${expectedMD5} )`);
          .... 
          return true;
     }
});



为了解决这个问题,需要对引擎热更新部分稍加改造。

下面以android 环境为例进行详细说明。



第一步:增加 md5库, 放在 cocos2d-x/extensions/assets-manager文件夹下 。





第二步,改造AssetsManagerEx.h 和 AssetsManagerEx.cpp 增加默认校验方法



在AssetsManagerEx.h 增加函数声明:

private:
    virtual bool onVerifyDefault(const std::string storagePath, Manifest::Asset asset);



在AssetsManagerEx.cpp 实现函数:



bool AssetsManagerEx::onVerifyDefault(const std::string storagePath,Manifest::Asset asset)
{
    //cocos2d::log("onVerifyDefault 0");
    Data data = cocos2d::FileUtils::getInstance()->getDataFromFile(storagePath);
    if (data.isNull() ||(data.getSize()== 0 )){
        CCLOG("onVerifyDefault 1");
        return false;
    }
    std::string result = md5(data.getBytes(), data.getSize());
    //cocos2d::log("onVerifyDefault:%s - assetmd5:%s-resultmd5:%s",storagePath.c_str(),asset.md5.c_str(),result.c_str());
    if (memcmp(result.c_str(), asset.md5.c_str(), result.length()) == 0){
        CCLOG("onVerifyDefault 2");
        return  true;
    }
   // cocos2d::log("onVerifyDefault 3");
    return false;
}



在 AssetsManagerEx.cpp 的 onSuccess方法中,做md5比较部分改造。



当_verifyCallback 为nullptr 时,采用默认 onVerifyDefault 进行校验,如下:



void AssetsManagerEx::onSuccess(const std::string &/*srcUrl*/, const std::string &storagePath, const std::string &customId)
{
    if (customId == VERSION_ID)
    {
        _updateState = State::VERSION_LOADED;
        parseVersion();
    }
    else if (customId == MANIFEST_ID)
    {
        _updateState = State::MANIFEST_LOADED;
        parseManifest();
    }
    else
    {
        if (_downloadingTask.find(customId) != _downloadingTask.end()) {
            _downloadingTask.erase(customId);
        }
        bool ok = true;
        auto &assets = _remoteManifest->getAssets();
        auto assetIt = assets.find(customId);
        if (assetIt != assets.end())
        {
            Manifest::Asset asset = assetIt->second;
            if (_verifyCallback != nullptr)
            {
                ok = _verifyCallback(storagePath, asset);
            } else{
                ok =onVerifyDefault( storagePath,asset);
            }
        }
        if (ok)
        {
            bool compressed = assetIt != assets.end() ? assetIt->second.compressed : false;
            if (compressed)
            {
                decompressDownloadedZip(customId, storagePath);
            }
            else
            {
                fileSuccess(customId, storagePath);
            }
        }
        else
        {
            fileError(customId, "Asset file verification failed after downloaded");
        }
    }
}

第三步,修改 Android.mk,增加MD5.cpp 文件的编译

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE    := cocos_extension_static
LOCAL_MODULE_FILENAME := libextension
ifeq ($(USE_ARM_MODE),1)
LOCAL_ARM_MODE := arm
endif
LOCAL_SRC_FILES := \
assets-manager/MD5.cpp \
assets-manager/Manifest.cpp \
assets-manager/AssetsManagerEx.cpp \
assets-manager/CCEventAssetsManagerEx.cpp \
assets-manager/CCAsyncTaskPool.cpp \
LOCAL_CXXFLAGS += -fexceptions
LOCAL_C_INCLUDES := $(LOCAL_PATH)/. \
                    $(LOCAL_PATH)/.. \
                    $(LOCAL_PATH)/../cocos \
                    $(LOCAL_PATH)/../cocos/platform \
                    $(LOCAL_PATH)/../external/sources
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/. \
                           $(LOCAL_PATH)/..
include $(BUILD_STATIC_LIBRARY)



第四步,删除上层校验回调实现,默认采用c++新增的校验方法。

即:js 或ts 代码中不再调用 assetsManagers.setVerifyCallback 方法。



以上就是 Cocos Creator 热更新资源 md5值比较的调整,此方案可有效解决渲染线程卡顿问题。



下面是完整源码



MD5.h源码



#ifndef _LUA_MD5_H__
#define _LUA_MD5_H__
#include <stdio.h>
#include <string>
using namespace std;
class MD5 {
public:
  typedef unsigned int size_type; // must be 32bit
  MD5();
  MD5(const std::string& text);
  void update(const unsigned char *buf, size_type length);
  void update(const char *buf, size_type length);
  MD5& finalize();
  std::string hexdigest(bool bUpper = false) const;
  friend std::ostream& operator<<(std::ostream&, MD5 md5);
private:
  void init();
  typedef unsigned char uint1; //  8bit
  typedef unsigned int uint4;  // 32bit
  enum {
    blocksize = 64
  }; // VC6 won't eat a const static int here
  void transform(const uint1 block[blocksize]);
  static void decode(uint4 output[], const uint1 input[], size_type len);
  static void encode(uint1 output[], const uint4 input[], size_type len);
  bool finalized;
  uint1 buffer[blocksize];
  uint4 count[2];
  uint4 state[4];
  uint1 digest[16];
  static inline uint4 F(uint4 x, uint4 y, uint4 z);
  static inline uint4 G(uint4 x, uint4 y, uint4 z);
  static inline uint4 H(uint4 x, uint4 y, uint4 z);
  static inline uint4 I(uint4 x, uint4 y, uint4 z);
  static inline uint4 rotate_left(uint4 x, int n);
  static inline void FF(uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s,
      uint4 ac);
  static inline void GG(uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s,
      uint4 ac);
  static inline void HH(uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s,
      uint4 ac);
  static inline void II(uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s,
      uint4 ac);
};
extern std::string md5(const std::string str);
extern std::string md5(const wchar_t* pwstr);
extern std::string md5(const unsigned char *buf, const unsigned int length);
#endif







相关文章
|
2月前
|
移动开发 监控 小程序
mPaaS常见问题之uniapp ios端云打包的配置config文件如何解决
mPaaS(移动平台即服务,Mobile Platform as a Service)是阿里巴巴集团提供的一套移动开发解决方案,它包含了一系列移动开发、测试、监控和运营的工具和服务。以下是mPaaS常见问题的汇总,旨在帮助开发者和企业用户解决在使用mPaaS产品过程中遇到的各种挑战
|
10月前
|
Java Android开发
安卓增加或修改现有app apk的功能(apk功能扩展)
安卓增加或修改apk android apk app的功能(apk功能扩展)
安卓增加或修改现有app apk的功能(apk功能扩展)
|
2月前
|
缓存 小程序 Android开发
mPaaS问题之iOS调用插件的时候提示没有配置mpaas. Config文件如何解决
mPaaS配置是指在mPaaS平台上对移动应用进行的各项设置,以支持应用的定制化和优化运行;本合集将提供mPaaS配置的操作指南和最佳实践,助力开发者高效管理和调整移动应用的设置。
|
2月前
|
小程序 Android开发 iOS开发
mPaaS问题之Ios调小程序报错如何解决
mPaaS小程序是阿里巴巴移动平台服务(mPaaS)推出的一种轻量级应用解决方案,旨在帮助开发者快速构建跨平台的小程序应用;本合集将聚焦mPaaS小程序的开发流程、技术架构和最佳实践,以及如何解决开发中遇到的问题,从而助力开发者高效打造和维护小程序应用。
mPaaS问题之Ios调小程序报错如何解决
|
8月前
|
开发工具
[√]cocos2dx particleSystem渲染过程解读、优化的思考
[√]cocos2dx particleSystem渲染过程解读、优化的思考
44 0
|
9月前
Cocos Creator 解决热更新资源md5比较引发卡顿问题(四)
Cocos Creator 解决热更新资源md5比较引发卡顿问题
102 0
|
9月前
Cocos Creator 解决热更新资源md5比较引发卡顿问题(三)
Cocos Creator 解决热更新资源md5比较引发卡顿问题
127 0
|
9月前
Cocos Creator 解决热更新资源md5比较引发卡顿问题(二)
Cocos Creator 解决热更新资源md5比较引发卡顿问题
|
9月前
|
UED
CocosCreator 面试题(七)优化cocos creator 包体体积
CocosCreator 面试题(七)优化cocos creator 包体体积
290 0
|
移动开发 weex API
weex在iOS环境加载本地图片的方法
weex在iOS环境加载本地图片的方法
145 0
weex在iOS环境加载本地图片的方法