123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208 |
- /** @format */
- import {Log} from '../utils/LogUtils'
- export class HotOptions {
- OnVersionInfo: Function
- OnNeedToUpdate: Function
- OnNoNeedToUpdate: Function
- OnUpdateFailed: Function
- OnUpdateSucceed: Function
- OnUpdateProgress: Function
- check() {
- for (let key in this) {
- if (key !== 'check') {
- if (!this[key]) {
- Log.warn(`参数HotOptions.${key}未设置!`)
- return false
- }
- }
- }
- return true
- }
- }
- class Hot {
- _assetsMgr: jsb.AssetsManager = null
- _options: HotOptions = null
- _state = Hot.State.None
- static State = {
- None: 0,
- Check: 1,
- Update: 2,
- }
- // 检查更新
- checkUpdate() {
- if (!this._assetsMgr) {
- Log.warn('请先初始化')
- return false
- }
- if (this._assetsMgr.getState() === jsb.AssetsManager.State.UNINITED) {
- Log.error('未初始化')
- return false
- }
- if (!this._assetsMgr.getLocalManifest().isLoaded()) {
- console.log('加载本地 manifest 失败 ...')
- return false
- }
- this._assetsMgr.setEventCallback(this._checkUpdateCb.bind(this))
- this._state = Hot.State.Check
- // 下载version.manifest,进行版本比对
- this._assetsMgr.checkUpdate()
- return true
- }
- hotUpdate() {
- if (!this._assetsMgr) {
- Log.warn('请先初始化')
- return
- }
- this._assetsMgr.setEventCallback(this._hotUpdateCallBack.bind(this))
- this._state = Hot.State.Update
- this._assetsMgr.update()
- }
- _checkUpdateCb(event) {
- let code = event.getEventCode()
- console.log('checkUpdate Code: ' + code)
- switch (code) {
- case jsb.EventAssetsManager.ERROR_NO_LOCAL_MANIFEST:
- case jsb.EventAssetsManager.ERROR_DOWNLOAD_MANIFEST:
- case jsb.EventAssetsManager.ERROR_PARSE_MANIFEST:
- this._onUpdateFailed(code)
- break
- case jsb.EventAssetsManager.ALREADY_UP_TO_DATE:
- console.log('已经和远程版本一致,无须更新')
- this._options.OnNoNeedToUpdate && this._options.OnNoNeedToUpdate(code)
- break
- case jsb.EventAssetsManager.NEW_VERSION_FOUND:
- console.log('发现新版本,请更新')
- this._options.OnNeedToUpdate && this._options.OnNeedToUpdate(code)
- break
- default:
- break
- }
- }
- _hotUpdateCallBack(event: jsb.EventAssetsManager) {
- let code = event.getEventCode()
- console.log(`hotUpdate Code: ${code}`)
- switch (code) {
- case jsb.EventAssetsManager.UPDATE_PROGRESSION:
- console.log('更新中...')
- if (this._state === Hot.State.Update) {
- this._options.OnUpdateProgress && this._options.OnUpdateProgress(event)
- } else {
- // 检查状态下,不回调更新进度
- }
- break
- case jsb.EventAssetsManager.UPDATE_FINISHED:
- console.log('更新成功')
- this._onUpdateFinished()
- break
- case jsb.EventAssetsManager.ASSET_UPDATED:
- // 不予理会的消息事件
- break
- default:
- this._onUpdateFailed(code)
- break
- }
- }
- _onUpdateFailed(code) {
- this._assetsMgr.setEventCallback(null)
- this._options.OnUpdateFailed && this._options.OnUpdateFailed(code)
- }
- // 更新完成
- _onUpdateFinished() {
- this._assetsMgr.setEventCallback(null)
- let searchPaths = jsb.fileUtils.getSearchPaths()
- let newPaths = this._assetsMgr.getLocalManifest().getSearchPaths()
- console.log('[HotUpdate] 搜索路径: ' + JSON.stringify(newPaths))
- Array.prototype.unshift(searchPaths, newPaths)
- cc.sys.localStorage.setItem('HotUpdateSearchPaths', JSON.stringify(searchPaths))
- jsb.fileUtils.setSearchPaths(searchPaths)
- this._options.OnUpdateSucceed && this._options.OnUpdateSucceed()
- }
- showSearchPath() {
- console.log('========================搜索路径========================')
- let searchPaths = jsb.fileUtils.getSearchPaths()
- for (let i = 0; i < searchPaths.length; i++) {
- console.log('[' + i + ']: ' + searchPaths[i])
- }
- console.log('======================================================')
- }
- // ------------------------------初始化------------------------------
- init(manifest: cc.Asset, opt: HotOptions) {
- if (!cc.sys.isNative) {
- return
- }
- if (!opt.check()) {
- return
- }
- this._options = opt
- if (this._assetsMgr) {
- return
- }
- this.showSearchPath()
- let url = manifest.nativeUrl
- // if (cc.loader.md5Pipe) {
- // url = cc.loader.md5Pipe.transformURL(url)
- // }
- let storagePath = (jsb.fileUtils ? jsb.fileUtils.getWritablePath() : '/') + 'remote-asset'
- this._assetsMgr = new jsb.AssetsManager(url, storagePath, (versionA, versionB) => {
- // 比较版本
- console.log('客户端版本: ' + versionA + ', 当前最新版本: ' + versionB)
- this._options.OnVersionInfo({local: versionA, server: versionB})
- let vA = versionA.split('.')
- let vB = versionB.split('.')
- for (let i = 0; i < vA.length; ++i) {
- let a = parseInt(vA[i])
- let b = parseInt(vB[i] || '0')
- if (a == b) {
- continue
- } else {
- return a - b
- }
- }
- if (vB.length > vA.length) {
- return -1
- } else {
- return 0
- }
- })
- this._assetsMgr.setVerifyCallback((assetsFullPath, asset) => {
- let {compressed, md5, path, size} = asset
- if (compressed) {
- return true
- } else {
- return true
- }
- })
- if (cc.sys.os === cc.sys.OS_ANDROID) {
- // 安卓手机设置 最大并发任务数量限制为2
- // this._assetsMgr.setMaxConcurrentTask(10);
- }
- let localManifest = this._assetsMgr.getLocalManifest()
- console.log('[HotUpdate] 热更新资源存放路径: ' + storagePath)
- console.log('[HotUpdate] 本地manifest路径: ' + url)
- console.log('[HotUpdate] local packageUrl: ' + localManifest.getPackageUrl())
- console.log('[HotUpdate] project.manifest remote url: ' + localManifest.getManifestFileUrl())
- console.log('[HotUpdate] version.manifest remote url: ' + localManifest.getVersionFileUrl())
- }
- }
- let hotInstance = new Hot()
- export default hotInstance
|