手机内存里的CheckRescheckupdate.exe 广告是什么东西

checkresupdate是什么_百度知道
checkresupdate是什么
checkresupdate是什么
我有更好的答案
check result date检查结果日期
为您推荐:
其他类似问题
换一换
回答问题,赢新手礼包
个人、企业类
违法有害信息,请在下方选择后提交
色情、暴力
我们会通过消息、邮箱等方式尽快将举报结果通知您。手机内存里的CheckResUpdate是什么东西_百度知道
该问题可能描述不清,建议你
手机内存里的CheckResUpdate是什么东西
我有更好的答案
微信后台使劲跑流量
这个英文的意思好像是检查更新
1条折叠回答
为您推荐:
其他类似问题
换一换
回答问题,赢新手礼包
个人、企业类
违法有害信息,请在下方选择后提交
色情、暴力
我们会通过消息、邮箱等方式尽快将举报结果通知您。查看: 3044|回复: 0
大家都深有体会安卓系统的手机内存使用很快,而苹果的总是保持很稳定;那是因为安卓的有些软件开发工程师很流氓,在进行软件卸载时不会把缓存清理掉,但是苹果的IOS系统就不存在这样的现象,他们对第三方的软件开发控制很严格。安卓开源就导致中毒、垃圾沉积,如果Root开放,用户信息也就有可能随之外泄。下面就给大家以小米手机MIUI系统为例,介绍一下手机里面的文件夹:
常用程序生成的文件夹,根据自己安装的程序来选择是否删除
1、.android_secure是官方app2sd的产物,删了之后装到sd卡中的软件就无法使用了。不可删!
2、.Bluetooth顾名思义,用蓝牙之后就会有这个。
3、.mobo顾名思义,Moboplayer的缓存文件。
4、.QQ顾名思义,QQ的缓存文件。
5、.quickoffice顾名思义,quickoffice的缓存文件。
6、.switchpro顾名思义,switchprowidget(多键开关)的缓存文件。
7、.ucdlres顾名思义,UC迅雷的缓存文件。
8、albumart音乐专辑封面的缓存文件夹。
9、albums相册缩略图的缓存文件夹10、Android比较重要的文件夹,里面是一些程序数据,比如googlemap的地图缓存。
11、backups一些备份文件,比如联系人导出到SD卡时会导入到此文件夹。
12、baidu顾名思义,掌上百度、百度输入法之类程序的缓存文件夹。
13、bugtogo系统出现问题的时候会形成一些报告文件,存放于此文件夹。不建议删
14、cmp个人初步判断是音乐的缓存文件夹。
15、data同样是缓存数据的文件夹,与Android性质类似。
16、DCIM相机的缓存文件夹。
17、documentsDocumentsToGo的相关文件夹。
18、etouch易行的缓存文件夹。
19、extractedandrozip等解压缩软件默认的解压目录。
20、gameloft顾名思义,gameloft游戏数据包存放的文件夹。
21、handcent顾名思义handcent(超级短信)数据文件夹。
22、handyCurrency货币汇率相关的文件夹,装了handycalc(科学计算器)之后才会有。
23、ireader顾名思义,ireader的缓存文件夹。
24、KingReader顾名思义,开卷有益的缓存文件夹。
25、LazyListApplanet(黑市场)的缓存目录,也许和其他程序也有关,暂时不太清楚。
26、LOST.DIR卡上丢失或出错的文件会跑这里,此目录无用,删了会自动生成。
27、moji顾名思义,墨迹天气的缓存目录。
28、MusicFolderspoweramp产生的缓存文件夹。
29、openfeint顾名思义,openfeint的缓存文件夹。
30、Picstore图片浏览软件建立的一个目录。
31、Playlists播放列表的缓存文件夹。
32、renren顾名思义,人人网客户端的缓存文件夹。
33、screenshot截屏图片保存的目录,screenshot这个软件的。
34、ShootMe顾名思义,shootme截屏后图片文件保存的目录。
35、SmartpixGamesSmartpixGames出品游戏的缓存文件夹,比如Jewellust。
36、sogou顾名思义,搜狗拼音的缓存文件夹。
37、SpeedSoftware RE管理器 的缓存文件夹。
38、SystemAppBackupSystemAppremove(深度卸载)备份系统文件后,备份文件保存的目录。
39、TalkingFriendstalkingtom(会说话的tom猫)录制的视频文件所保存的目录。
40、Tencent顾名思义,腾讯软件的缓存目录,比如QQ。(与上面的.QQ文件夹并不相同)
41、TitaniumBackup顾名思义,钛备份备份的程序所保存的目录。
42、TunnyBrowser感觉是海豚浏览器的缓存目录,但不知道为什么叫这个名字,金枪鱼浏览器…..
43、UCDLFilesUC迅雷下载文件的保存目录。
44、UCDownloadsUC浏览器下载文件的保存目录。
45、VIEVignette(晕影相机)的缓存目录。
46、yd_historysYoudao有道词典搜索历史的缓存目录。
47、yd_speech有道词典单词发音的缓存目录。
48、youmicache删掉后还会自动生成,悠米广告的缓存目录,广告程序内嵌在其他程序中。
49、.新建文件夹检查下是不是你自己放什么图的文件夹。
50、sina新浪微博。
51、playnow索尼爱立信的在线商店playnow
52、PlayerPro好评最多的音乐播放器
53、Mcdonalds手机里的Mcdonalds软件的缓存,删除后,软件要重新联网下载才能使用。不建议删除
54、mhc手机里装了**软件后,**后的文件就在这里。
55、sgsupdate三国杀的升级文件的安装包就在这
56、bluetooth手机蓝牙接收的文件默认在这里
57、anwo安沃形成的缓存文件
58、Alarms闹钟形成的文件夹,可能放置铃声
59、AndroidOptimizer安装安卓优化大师的缓存文件夹初步认为
60、audiostat 是新版QQ浏览器形成的
61、Gostore 由go商城产生
62、jingdong 顾名思义 京东商城app生成
62、kwmusic 酷我音乐盒存放下载音乐
63、LauncherWP8 winp8桌面产的缓存文件夹
64、letao2 乐淘程序产生缓存文件夹
65、letv 乐视视频缓存文件夹
66、luckypatcher 幸运破解器产生的
67、miliao 看拼音..这个大家懂的
68、MIUI这个...刷MIUI的必须有不能删 关系到各种功能正使用
69、moji 墨迹天气各种皮肤等等存放文件
70、msf 手机qq生成 可以删除
71、pandahome2 熊猫桌面生成文件夹
72、pptv PPTV视频缓存 下载视频存放在该文件夹
73、QQBrowser QQ浏览器缓存。下载东西存放地 建议清理里面download下载的东西
74、qqmusic QQ音乐生成 有音乐在里面 删之前注意下歌曲有用否
75、qvod这个男人都懂得!!!
76、Renren 人人安卓 里面有大量下载缓存图片,看个人情况删除
77、Qzone qq空间客户端缓存文件夹
78、sixin 私信客户端
79、Tencent 管理腾讯软件的总文件夹
80、TitaniumBackup 钛备份生成,平时备份文件保存在这 删之前慎重
81、ttpod 天天动听生成
82、UCDownloads UC浏览器文件夹 建议常常清理里面文件
83、yinyuelieshou 音乐猎手生成文件夹 存放录音等等
84、yy YY语音生成
85、download_rom 系统升级下载OTA包和完整包存放文件夹
86、duokan 多看阅读 有了ideader果断删了这个
87、BaiduMapSdk 百度地图 还是有较多的缓存
88、Baidu_music百度音乐 下载的音乐存于此
89、sina 新浪微博之类的
90、QQSecureDownload qq之类的软件下载 觉得没用删了
91、shuame 貌似某刷机软件残留的 删了
92、com.taobao.taobao 淘宝软件
93、baidu百度输入
94、ibuka 布卡漫画 删除后本地下载的漫画随之删除
95、zapya 快牙传输生成文件夹
96、wowfish 捕鱼达人 卸载游戏后可删除
97、xmtopic 具体不知 貌似跟金山快盘绑定小米网盘有关
98、VoiceAssistant 语音助手生成
99、uccwoutput 存放UC浏览器皮肤文件夹 删掉后可能导致UC皮肤失效
100、Ultimate custom clock widget 自定义时钟 删除后导致自定义时钟皮肤失效
101、simeji 日语输入法。貌似一般童鞋用不着..
102、RMS 进入木马清理或者临时优化生成 可以删除
103、qqpim qq同步助手生成 删了也会自动重建
104、qqkart qq卡丁车生成 不玩了可以删除
105、QQ_Screenshot qq自带截图功能所截图存放此文件夹 删除后截图丢失
106、podcast 播客
107、p2pcache 下载视频生成缓存 可删除
108、.0102 安装程序留下缓存文件夹 删掉没影响
109、.ads 暂不清楚 但是删除后没有不良反应
110、.appchina 应用汇下载缓存文件 应用没卸载的话删掉依旧生成
111、12580 中国移动12580
112、AIReader 阅读软件产生113、BaiduWenKurt 由百度文库创建,可以删除,重启软件会再次生成114、cmpay 中国移动手机支付客户端产生115、CarBox 由汽车盒子客户端生成116、Cut the Rope 由Zeptolab公司开发《割绳子》117、feiliao 中国移动开发即时聊天软件飞聊118、fetlion中国移动开发聊天软件飞信,免费发短信
_com.maxmpz.audioplayerPowerAMP音乐播放器形成 像我已经卸载的就可以毫无压力的删除
com.android.fileexplorer 小米文件管理倘若你还想正常使用MIUI文件管理就别动这个!
com.android.gallery3dandroid系统自带的3D图片浏览器
com.android.providers.media 多媒体文件 不建议删除!
com.bulkypix.abyescape.android 游戏阿比大逃亡中文版 还是很好玩的
com.chartboost.sdk图库缓存文件 就算删了也会生成
com.disney.brave_google 神庙逃亡之勇敢者之心
com.gameloft.android.ANMP.GloftD3HM地牢猎手3 这个真的好大 1G
com.google.android.apps.maps 谷歌地图
com.miui.gallery 图库 别动!
com.renren.mobile.android 人人客户端
com.nexon.kartriderrush.android.olleh跑跑卡丁车 很喜欢不删不删
com.sds.android.ttpod 天天动听,果断删了
com.spritefish.fastburstcamera 连拍相机 用的少 删了
com.xiaomi.channel MIUI程序 不删
com.xiaomi.shop 小米商城 删了你就用不了
com.youku.phone 手机优酷 不用就删了
tv.danmaku.bili bilibili客户端~宅属最爱~
以上有些软件没有提及到的希望大家补充….O(∩_∩)O谢谢………
请输入验证码:
站长推荐 /2
祝移动叔叔全体会员在新的一年里,万事如意,事业兴旺,生活美满,身体安康!
为了回馈大家对“川语川韵”的支持,我们这次举办了一系列微信公众号福利活动,一大波礼品带着大家一起装逼一起飞!
移动叔叔. 版权所有,专业的网络售后平台 (
商务合作||||Pages: 1/7
主题 : quick-cocos2d-x的热更新机制实现(终极版)
级别: 侠客
可可豆: 349 CB
威望: 268 点
在线时间: 67(时)
发自: Web Page
来源于&&分类
quick-cocos2d-x的热更新机制实现(终极版)&&&
本帖被 dualface 执行提前操作()
别在意那个标题中的“终极版”,那只是个噱头为了把你拉进来而已。就好像页游广告中的MM一样,你点了一定会被骗的。写文章是非常花时间的,尤其是写到大部分人都能看懂,且逻辑正确(不一定观点正确),言语清晰,没有错别字的程度。写这篇文章的主要目的,是把我的思路做一个整理以备查;次要目的,则是希望我的思路对你有帮助。简单的说,就是刷我的存在感(靠这么多人回帖)和你的优越感(靠这么傻B的文章都发上来我的方法比这好一百倍我就是不想告诉你们)。这篇文章成文都用了6个小时,前后修改了3次,标点符号和错别字改了许多。为了更多人能看到,我也只能用点小伎俩把你拉进来了。我不求你认同我的方法,只愿你看完后能有自己的思考。转身就走还来得及,但不要后悔哦……&&原文: Hot update in quick-cocos2d-x0 依赖这里说的热更新,指的是客户端的更新。大致的流程是,客户端在启动后访问更新api,根据更新api的反馈,下载更新资源,然后使用新的资源启动客户端,或者直接使用新资源不重启客户端。这种方式可以跳过AppStore的审核,避免了用户频繁下载、安装、覆盖产品包。我们一般使用这种方式快速修复产品BUG和增加新功能。本文基于
。 1 前言1.1 他山之石在实现这个机制之前,我研究了这几篇文章: by SunLightJuly by Henry by 西门大官人另外,我也查看了
。不幸的是,这几个方案我都不能直接拿来用。因此思考再三,还是自己写了一套方案。==重要提醒==这篇文章很长,但我不愿意将其分成多个部分。这本来就是一件事,分开的话有种开房时洗完澡妹子却说两个小时后才能来。这中间干点啥呢?所以,如果你不能坚持两个小时(能么?不能?),或者你的持久度不能坚持到把这篇文章看完(大概要10~30分钟吧),那还是不要往下看的比较好。当然,你也可能坚挺了30分钟之后才发现妹子是凤姐,不要怪我这30分钟里面没开灯哦……1.2 为什么要重复造轮子上面的几个方案侧重于尽量简化用户(使用此方案的程序员)的操作,而简化带来的副作用就是会损失一些灵活性。Roberto Ierusalimschy 在
第15章开头说:通常,Lua不会设置规则(policy)。相反,Lua会提供许多强有力的机制来使开发者有能力实现出最适合的规则。我认为更新模块也不应该设置规则,而是尽可能提供一些机制来满足程序员的需要。这些机制并不是我发明的,而是Lua和quick本来就提供的。让程序员自己实现自己的升级系统,一定比我这个无证野路子的方法更好.因此,本文中讲述的并非是一套通用的机制,而是我根据上面说到的这些机制实现的一套适合自己的方法。当然你可以直接拿去用,但要记住:用的好,请告诉你的朋友。出了问题,请别找我。1.3 需求的复杂性热更新有许多的必要条件,每个产品的需求可能都不太相同。例如,每个产品的版本号设计都不太相同,有的有大版本、小版本;有的则有主版本、次版本、编译版本。我以前的习惯,是在主版本变化的时候需要整包更新,而次版本变化代表逻辑更新,编译版本代表资源更新等等。这些需要自己来定义升级规则。再例如,有的产品希望逐个下载升级包,有的产品希望把所有资源打包成一个升级包;有的产品直接使用文件名作为资源名在游戏中调用,而有的产品会把资源名改为指纹码(例如MD5)形式来实现升级的多版本共存和实时回滚,还有的产品甚至要求能在用户玩游戏的过程中完成自动更新。 那套机制就太死板,在真实的产品中不修改很难使用。而我也不建议使用 CCUserDefault 这种东西——在Lua的世界里,为什么要用XML做配置文件?如果抽象出我的需求,其实只有1点:能更新一切这个说的有点大了,准确的说,应该是 能更新一切Lua代码与资源 。如果你的整个游戏都是Lua写的(对于quick的项目来说应该是这样),其实也就是更新一切。1.4 版本号设计关于上面
中提到的版本号的问题,可以参考一下这篇文章: 。我基于语义化版本设计了一套规则在团队内部使用: 。在这里,我尽量详细地阐述我的思路和做法,抛砖引玉吧。2 特色基本的热更新功能就不说了大家都有。我这套机制还有如下几个特色:2.1 可以更新 frameworks_precompiled.zip 模块为了行文方便,后面会把 frameworks_precompiled.zip 简称为 framework 。frameworks 模块是 quick 的核心模块,在quick 生成的项目中,它直接在 AppDelegate.cpp 中载入 main.lua 之前进行载入。如下:bool AppDelegate::applicationDidFinishLaunching(){    // initialize director    CCDirector *pDirector = CCDirector::sharedDirector();    pDirector-&setOpenGLView(CCEGLView::sharedOpenGLView());    pDirector-&setProjection(kCCDirectorProjection2D);    // set FPS. the default value is 1.0/60 if you don't call this    pDirector-&setAnimationInterval(1.0 / 60);    // register lua engine    CCLuaEngine *pEngine = CCLuaEngine::defaultEngine();    CCScriptEngineManager::sharedManager()-&setScriptEngine(pEngine);    CCLuaStack *pStack = pEngine-&getLuaStack();#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS || CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)    // load framework    pStack-&loadChunksFromZIP(&res/framework_precompiled.zip&);    // set script path    string path = CCFileUtils::sharedFileUtils()-&fullPathForFilename(&scripts/main.lua&);    ......这可以说明这个核心模块对quick的重要性。正因为它重要,所以必须要能更新它。2.2 可以更新 update 模块自身更新功能是客户端启动后载入的第一个lua模块,它负责载入更新资源,以及启动主项目。一般情况下,这个模块是不需要改动的。对它进行改动,既不科学,也不安全(安全啊……)。但是万一呢?大家知道策划和运营同学都是二班的,或许哪天就有二班同学找你说:改改怕什么?又不会怀孕…… 所以这个必须有。2.3 纯lua实现把这个拿出来说纯粹是撑数的。不凑个三大特色怎么好意思?上面SunLightJuly和Henry同学的方案当然也是纯lua的。用quick你不搞纯lua好意思出来混?小心廖大一眼瞪死你。当然,我这个不是纯lua的,我基于
的代码实现了一个 Updater 模块。而且,我还改了 AppDelegate 中的启动代码。所以,你看,我不仅是撑数,还是忽悠。[ 此帖被zong在 09:41重新编辑 ]
本帖最近评分记录: 共1条评分记录
http://zengrong.net注册的时候手抖(jian)少输入一个字母,所以就这样了……
级别: 侠客
可可豆: 349 CB
威望: 268 点
在线时间: 67(时)
发自: Web Page
3 Updater(C++) 中提供了下载资源,访问更新列表,解压zip包,删除临时文件,设置搜索路径等等一系列的功能。但它的使用方式相当死板,我只能传递一个获取版本号的地址,一个zip包的地址,一个临时文件夹路径,然后就干等着。期间啥也干不了。当然,我可以通过 quick 为其增加的 registerScriptHandler 方法让lua得知下载进度和网络状态等等。但下载进度的数字居然以事件名的方式通过字符串传过来的!这个就太匪夷所思了点。于是,我对这个 AssetsManager 进行了修改。因为修改的东西实在太多,改完后就不好意思再叫这个名字了(其实主要是现在的名字比较短 XD)。我们只需要记住这个 Updater 是使用 AssetsManager 修改的即可。在上面SunLightJuly和Henry同学的方法中,使用的是 CCHTTPRequest 来获取网络资源的。CCHTTPRequest 封装了cURL 操作。而在 Updater 中,是直接封装的 cURL 操作。在我的设计中,逻辑应该尽量放在lua中,C++部分只提供功能供lua调用。因为lua可以进行热更新,而C++部分则只能整包更新。 主要实现的内容如下:3.1 删除了不需要的方法get和set相关的一堆方法都被删除了。new对象的时候也不必传递参数了。3.2 增加 getUpdateInfo 方法这个方法通过HTTP协议获取升级列表数据,获取到的数据直接返回,C++并不做处理。3.3 修改 update 方法这个方法通过HTTP协议下载升级包,需要提供四个参数:zip文件的url;zip文件的保存位置;zip 文件的解压临时目录;解压之前是否需要清空临时目录。3.4 修改事件类型我把把传递给lua的事件分成了四种类型:3.4.1 UPDATER_MESSAGE_UPDATE_SUCCEED事件名为 success,代表更新成功,zip文件下载并解压完毕;3.4.2 UPDATER_MESSAGE_STATE事件名为 state,更新过程中的状态(下载开始、结束,解压开始、结束)也传递给了lua。这个方法是这样实现的:void Updater::Helper::handlerState(Message *msg){    StateMessage* stateMsg = (StateMessage*)msg-&    if(stateMsg-&manager-&_delegate)    {        stateMsg-&manager-&_delegate-&onState(stateMsg-&code);    }    if (stateMsg-&manager-&_scriptHandler)    {        std::string stateM        switch ((StateCode)stateMsg-&code)        {            case kDownStart:                stateMessage = &downloadStart&;                                           case kDownDone:                stateMessage = &downloadDone&;                                           case kUncompressStart:                stateMessage = &uncompressStart&;                           case kUncompressDone:                stateMessage = &uncompressDone&;                                           default:                stateMessage = &stateUnknown&;        }                CCScriptEngineManager::sharedManager()            -&getScriptEngine()            -&executeEvent(                           stateMsg-&manager-&_scriptHandler,                           &state&,                           CCString::create(stateMessage.c_str()),                           &CCString&);    }        delete ((StateMessage*)msg-&obj);}3.4.3 UPDATER_MESSAGE_PROGRESS事件名为 progress,传递的对象为一个 CCInteger ,代表进度。详细的实现可以看 。3.4.4 UPDATER_MESSAGE_ERROR事件名为 error,传递的对象是一个 CCString,值有这样几个:errorCreateFileerrorNetworkerrorNoNewVersionerrorUncompresserrorUnknown方法的实现和上面的 UPDATER_MESSAGE_STATE 类似,这里就不贴了。详细的实现可以看 。Updater(C++) 部分只做了这些苦力工作,而具体的分析逻辑(分析getUserInfo返回的数据决定是否升级、如何升级和升级什么),下载命令的发出(调用update方法),解压成功之后的操作(比如合并新文件到就文件中,更新文件索引列表等等),全部需要lua来做。下面是一个处理Updater(C++)事件的lua函数的例子。function us._updateHandler(event, value)    updater.state = event    if event == &success& then        updater.stateValue = value:getCString()        -- 成功之后更新资源列表,合并新资源        updater.updateFinalResInfo()        -- 调用成功后的处理函数        if us._succHandler then            us._succHandler()        end    elseif event == &error& then        updater.stateValue = value:getCString()    elseif event == &progress& then        updater.stateValue = tostring(value:getValue())    elseif event == &state& then        updater.stateValue = value:getCString()    end    -- us._label 是一个CCLabelTTF,用来显示进度和状态    us._label:setString(updater.stateValue)    assert(event ~= &error&,         string.format(&Update error: %s !&, updater.stateValue))endupdater:registerScriptHandler(us._updateHandler)
http://zengrong.net注册的时候手抖(jian)少输入一个字母,所以就这样了……
级别: 侠客
可可豆: 349 CB
威望: 268 点
在线时间: 67(时)
发自: Web Page
4. update包(lua)update包是整个项目的入口包,quick会首先载入这个包,甚至在 framework 之前。4.1 为update包所做的项目修改我修改了quick项目文件 AppDelegate.cpp 中的 applicationDidFinishLaunching 方法,使其变成这样:bool AppDelegate::applicationDidFinishLaunching(){    // initialize director    CCDirector *pDirector = CCDirector::sharedDirector();    pDirector-&setOpenGLView(CCEGLView::sharedOpenGLView());    pDirector-&setProjection(kCCDirectorProjection2D);    // set FPS. the default value is 1.0/60 if you don't call this    pDirector-&setAnimationInterval(1.0 / 60);    // register lua engine    CCLuaEngine *pEngine = CCLuaEngine::defaultEngine();    CCScriptEngineManager::sharedManager()-&setScriptEngine(pEngine);    CCLuaStack *pStack = pEngine-&getLuaStack();        string gtrackback = &\    function __G__TRACKBACK__(errorMessage) \    print(\&----------------------------------------\&) \    print(\&LUA ERROR: \& .. tostring(errorMessage) .. \&\\n\&) \    print(debug.traceback(\&\&, 2)) \    print(\&----------------------------------------\&) \    end&;    pEngine-&executeString(gtrackback.c_str());        // load update framework    pStack-&loadChunksFromZIP(&res/lib/update.zip&);        string start_path = &require(\&update.UpdateApp\&).new(\&update\&):run(true)&;    CCLOG(&------------------------------------------------&);    CCLOG(&EXECUTE LUA STRING: %s&, start_path.c_str());    CCLOG(&------------------------------------------------&);    pEngine-&executeString(start_path.c_str());       }原来位于 main.lua 中的 __G_TRACKBACK__ 函数(用于输出lua报错信息)直接包含在C++代码中了。那么现在 main.lua 就不再需要了。同样的,第一个载入的模块变成了 res/lib/update.zip,这个zip也可以放在quick能找到的其它路径中,使用这个路径只是我的个人习惯。最后,LuaStack直接执行了下面这句代码启动了 update.UpdateApp 模块:require(&update.UpdateApp&).new(&update&):run(true);4.2 update包中的模块update包有三个子模块,每个模块是一个lua文件,分别为:update.UpdateApp 检测更新,决定启动哪个模块。update.updater 负责真正的更新工作,与C++通信,下载、解压、复制。update.updateScene 负责在更新过程中显示界面,进度条等等。对于不同的大小写,是因为在我的命名规则中,类用大写开头,对象是小写开头。 update.UpdateApp 是一个类,其它两个是对象(table)。下面的 4.3、4.4、4.5 将分别对这3个模块进行详细介绍。4.3 update.UpdateApp下面是入口模块 UpdateApp 的内容:--- The entry of Game-- @author zrong(zengrong.net)-- Creation local UpdateApp = {}UpdateApp.__cname = &UpdateApp&UpdateApp.__index = UpdateAppUpdateApp.__ctype = 2local sharedDirector = CCDirector:sharedDirector()local sharedFileUtils = CCFileUtils:sharedFileUtils()local updater = require(&update.updater&)function UpdateApp.new(...)    local instance = setmetatable({}, UpdateApp)    instance.class = UpdateApp    instance:ctor(...)    return instanceendfunction UpdateApp:ctor(appName, packageRoot)    self.name = appName    self.packageRoot = packageRoot or appName    print(string.format(&UpdateApp.ctor, appName:%s, packageRoot:%s&, appName, packageRoot))    -- set global app    _G[self.name] = selfendfunction UpdateApp:run(checkNewUpdatePackage)    --print(&I am new update package&)    local newUpdatePackage = updater.hasNewUpdatePackage()    print(string.format(&UpdateApp.run(%s), newUpdatePackage:%s&,         checkNewUpdatePackage, newUpdatePackage))    if  checkNewUpdatePackage and newUpdatePackage then        self:updateSelf(newUpdatePackage)    elseif updater.checkUpdate() then        self:runUpdateScene(function()            _G[&finalRes&] = updater.getResCopy()            self:runRootScene()        end)    else        _G[&finalRes&] = updater.getResCopy()        self:runRootScene()    endend-- Remove update package, load new update package and run it.function UpdateApp:updateSelf(newUpdatePackage)    print(&UpdateApp.updateSelf &, newUpdatePackage)    local updatePackage = {        &update.UpdateApp&,        &update.updater&,        &update.updateScene&,    }    self:_printPackages(&--before clean&)    for __,v in ipairs(updatePackage) do        package.preload[v] = nil        package.loaded[v] = nil    end    self:_printPackages(&--after clean&)    _G[&update&] = nil    CCLuaLoadChunksFromZIP(newUpdatePackage)    self:_printPackages(&--after CCLuaLoadChunksForZIP&)    require(&update.UpdateApp&).new(&update&):run(false)    self:_printPackages(&--after require and run&)end-- Show a scene for update.function UpdateApp:runUpdateScene(handler)    self:enterScene(require(&update.updateScene&).addListener(handler))end-- Load all of packages(except update package, it is not in finalRes.lib)-- and run root app.function UpdateApp:runRootScene()    for __, v in pairs(finalRes.lib) do        print(&runRootScene:CCLuaLoadChunksFromZip&,__, v)        CCLuaLoadChunksFromZIP(v)    end        require(&root.RootScene&).new(&root&):run()endfunction UpdateApp:_printPackages(label)    label = label or &&    print(&\npring packages &..label..&------------------&)    for __k, __v in pairs(package.preload) do        print(&package.preload:&, __k, __v)    end    for __k, __v in pairs(package.loaded) do        print(&package.loaded:&, __k, __v)    end    print(&print packages &..label..&------------------\n&)endfunction UpdateApp:exit()    sharedDirector:endToLua()    os.exit()endfunction UpdateApp:enterScene(__scene)    if sharedDirector:getRunningScene() then        sharedDirector:replaceScene(__scene)    else        sharedDirector:runWithScene(__scene)    endendreturn UpdateApp我来说几个重点。4.3.1 没有framework由于没有加载 framework,class当然是不能用的。所有quick framework 提供的方法都不能使用。我借用class中的一些代码来实现 UpdateApp 的继承。其实我觉得这个UpdateApp也可以不必写成class的。4.3.2 入口函数 update.UpdateApp:run(checkNewUpdatePackage)run 是入口函数,同时接受一个参数,这个参数用于判断是否要检测本地有新的 update.zip 模块。是的,run 就是那个在 AppDelegate.cpp 中第一个调用的lua函数。这个函数接受一个参数 checkNewUpdatePackage ,在C++调用 run 的时候,传递的值是 true 。如果这个值为真,则会检测本地是否拥有新的更新模块,这个检测通过 update.updater.hasNewUpdatePackage() 方法进行,后面会说到这个方法。本地有更新的 update 模块,则直接调用 updateSelf 来更新 update 模块自身;若无则检测是否有项目更新,下载更新的资源,解析它们,处理它们,然后启动主项目。这些工作通过 update.updater.checkUpdate() 完成,后面会说到这个方法。若没有任何内容需要更新,则直接调用 runRootScene 来显示主场景了。这后面的内容就交给住场景去做了,update 模块退出历史舞台。从上面这个流程可以看出。在更新完成之前,主要的项目代码和资源没有进行任何载入。这也就大致达到了我们 更新一切 的需求。因为所有的东西都没有载入,也就不存在更新。只需要保证我载入的内容是最新的就行了。因此,只要保证 update 模块能更新,就达到我们最开始的目标了。这个流程还可以保证,如果没有更新,甚至根本就不需要载入 update 模块的场景界面,直接跳转到游戏的主场景即可。有句代码在 run 函数中至关重要: _G[&finalRes&] = updater.getResCopy()finalRes 这个全局变量保存了本地所有的 原始/更新 资源索引。它是一个嵌套的tabel,保存的是所有资源的名称以及它们对应的 绝对/相对 路径的对应关系。后面会详述。4.3.3 更新自身 update.UpdateApp:updateSelf(newUpdatePackage)这是本套机制中最重要的一环。理解了它,你就知道更新一切其实没什么秘密。Lua本来就提供了这样一套机制。由于在 C++ 中已经将 update 模块载入了内存,那么要更新自身首先要做的是清除 Lua 的载入标记。Lua在两个全局变量中做了标记:package.preload 执行 CCLuaLoadChunksFromZIP 之后会将模块缓存在这里作为 require 的加载器;package.loaded 执行 require 的时候会先查询 package.loaded,若没有则会查询 package.preload 得到加载器,利用加载器加载模块,再将加载的模块缓存到 package.loaded 中。详细的机制可以阅读
15.1 require 函数。那么,要更新自己,只需要把 package.preload 和 package.loaded 清除,然后再用新的 模块填充 package.preload 即可。下面就是核心代码了: local updatePackage = {    &update.UpdateApp&,    &update.updater&,    &update.updateScene&,}for __,v in ipairs(updatePackage) do    package.preload[v] = nil    package.loaded[v] = nilend_G[&update&] = nilCCLuaLoadChunksFromZIP(newUpdatePackage)require(&update.UpdateApp&).new(&update&):run(false)如果不相信这么简单,可以用上面完整的 UpdateApp 模块中提供的 UpdateApp:_printPackages(label) 方法来检测。4.3.4 显示更新界面 update.UpdateApp:runUpdateScene(handler)update.updater.checkUpdate() 的返回是异步的,下载和解压都需要时间,在这段时间里面,我们需要一个界面。runUpdateScene 方法的作用就是显示这个界面。并在更新成功之后调用handler处理函数。4.3.5 显示主场景 update.UpdateApp:runRootScene()到了这里,update 包就没有作用了。但由于我们先前没有载入除 update 包外的任何包,这里必须先载入它们。我上面提到过,finalRes 这个全局变量是一个索引表,它的 lib 对象就是一个包含所有待载入的包(类似于 frameworks_precompiled.zip 这种)的列表。我们通过循环将它们载入内存。对于 root.RootScene 这个模块来说,就是标准的quick模块了,它可以使用quick中的任何特性。for __, v in pairs(finalRes.lib) do    print(&runRootScene:CCLuaLoadChunksFromZip&,__, v)    CCLuaLoadChunksFromZIP(v)endrequire(&root.RootScene&).new(&root&):run()4.3.5 怎么使用这个模块你如果要直接拿来就用,这个模块基本上不需要修改。因为本来它就没什么特别的功能。当然,你可以看完下面两个模块再决定。&&[ 此帖被zong在 11:23重新编辑 ]
http://zengrong.net注册的时候手抖(jian)少输入一个字母,所以就这样了……
级别: 侠客
可可豆: 349 CB
威望: 268 点
在线时间: 67(时)
发自: Web Page
4.4 update.updateScene这个模块用于显示更新过程的进度和一些信息。所有内容如下:-------- updateScene for update package.-- This is a object, not a class.-- In this scene, it will show download progress bar -- and state for uncompress.-- @author zrong(zengrong.net)-- Creation: local updater = require(&update.updater&)local sharedDirector         = CCDirector:sharedDirector()-- check device screen sizelocal glview = sharedDirector:getOpenGLView()local size = glview:getFrameSize()local display = {}display.sizeInPixels = {width = size.width, height = size.height}local w = display.sizeInPixels.widthlocal h = display.sizeInPixels.heightCONFIG_SCREEN_WIDTH = 1280 CONFIG_SCREEN_HEIGHT = 800CONFIG_SCREEN_AUTOSCALE = &FIXED_HEIGHT&local scale, scaleX, scaleYscaleX, scaleY = w / CONFIG_SCREEN_WIDTH, h / CONFIG_SCREEN_HEIGHTscale = scaleYCONFIG_SCREEN_WIDTH = w / scaleglview:setDesignResolutionSize(CONFIG_SCREEN_WIDTH, CONFIG_SCREEN_HEIGHT, kResolutionNoBorder)local winSize = sharedDirector:getWinSize()display.contentScaleFactor = scaledisplay.size               = {width = winSize.width, height = winSize.height}display.width              = display.size.widthdisplay.height             = display.size.heightdisplay.cx                 = display.width / 2display.cy                 = display.height / 2display.c_left             = -display.width / 2display.c_right            = display.width / 2display.c_top              = display.height / 2display.c_bottom           = -display.height / 2display.left               = 0display.right              = display.widthdisplay.top                = display.heightdisplay.bottom             = 0display.widthInPixels      = display.sizeInPixels.widthdisplay.heightInPixels     = display.sizeInPixels.heightprint(&# display in updateScene start&)print(string.format(&# us.CONFIG_SCREEN_AUTOSCALE      = %s&, CONFIG_SCREEN_AUTOSCALE))print(string.format(&# us.CONFIG_SCREEN_WIDTH          = %0.2f&, CONFIG_SCREEN_WIDTH))print(string.format(&# us.CONFIG_SCREEN_HEIGHT         = %0.2f&, CONFIG_SCREEN_HEIGHT))print(string.format(&# us.display.widthInPixels        = %0.2f&, display.widthInPixels))print(string.format(&# us.display.heightInPixels       = %0.2f&, display.heightInPixels))print(string.format(&# us.display.contentScaleFactor   = %0.2f&, display.contentScaleFactor))print(string.format(&# us.display.width                = %0.2f&, display.width))print(string.format(&# us.display.height               = %0.2f&, display.height))print(string.format(&# us.display.cx                   = %0.2f&, display.cx))print(string.format(&# us.display.cy                   = %0.2f&, display.cy))print(string.format(&# us.display.left                 = %0.2f&, display.left))print(string.format(&# us.display.right                = %0.2f&, display.right))print(string.format(&# us.display.top                  = %0.2f&, display.top))print(string.format(&# us.display.bottom               = %0.2f&, display.bottom))print(string.format(&# us.display.c_left               = %0.2f&, display.c_left))print(string.format(&# us.display.c_right              = %0.2f&, display.c_right))print(string.format(&# us.display.c_top                = %0.2f&, display.c_top))print(string.format(&# us.display.c_bottom             = %0.2f&, display.c_bottom))print(&# display in updateScene done&)display.ANCHOR_POINTS = {    CCPoint(0.5, 0.5),  -- CENTER    CCPoint(0, 1),      -- TOP_LEFT    CCPoint(0.5, 1),    -- TOP_CENTER    CCPoint(1, 1),      -- TOP_RIGHT    CCPoint(0, 0.5),    -- CENTER_LEFT    CCPoint(1, 0.5),    -- CENTER_RIGHT    CCPoint(0, 0),      -- BOTTOM_LEFT    CCPoint(1, 0),      -- BOTTOM_RIGHT    CCPoint(0.5, 0),    -- BOTTOM_CENTER}display.CENTER        = 1display.LEFT_TOP      = 2; display.TOP_LEFT      = 2display.CENTER_TOP    = 3; display.TOP_CENTER    = 3display.RIGHT_TOP     = 4; display.TOP_RIGHT     = 4display.CENTER_LEFT   = 5; display.LEFT_CENTER   = 5display.CENTER_RIGHT  = 6; display.RIGHT_CENTER  = 6display.BOTTOM_LEFT   = 7; display.LEFT_BOTTOM   = 7display.BOTTOM_RIGHT  = 8; display.RIGHT_BOTTOM  = 8display.BOTTOM_CENTER = 9; display.CENTER_BOTTOM = 9function display.align(target, anchorPoint, x, y)    target:setAnchorPoint(display.ANCHOR_POINTS[anchorPoint])    if x and y then target:setPosition(x, y) endendlocal us = CCScene:create()us.name = &updateScene&local localResInfo = nilfunction us._addUI()    -- Get the newest resinfo in ures.    local localResInfo = updater.getResCopy()    local __bg = CCSprite:create(us._getres(&res/pic/init_bg.png&))    display.align(__bg, display.CENTER, display.cx, display.cy)    us:addChild(__bg, 0)    local __label = CCLabelTTF:create(&Loading...&, &Arial&, 24)    __label:setColor(ccc3(255, 0, 0))    us._label = __label    display.align(__label, display.CENTER, display.cx, display.bottom+30)    us:addChild(__label, 10)endfunction us._getres(path)    if not localResInfo then        localResInfo = updater.getResCopy()    end    for key, value in pairs(localResInfo.oth) do        print(&us._getres:&, key, value)        local pathInIndex = string.find(key, path)        if pathInIndex and pathInIndex &= 1 then            print(&us._getres getvalue:&, path)            res[path] = value            return value        end    end    return pathendfunction us._sceneHandler(event)    if event == &enter& then        print(string.format(&updateScene \&%s:onEnter()\&&, us.name))        us.onEnter()    elseif event == &cleanup& then        print(string.format(&updateScene \&%s:onCleanup()\&&, us.name))        us.onCleanup()    elseif event == &exit& then        print(string.format(&updateScene \&%s:onExit()\&&, us.name))        us.onExit()        if DEBUG_MEM then            print(&----------------------------------------&)            print(string.format(&LUA VM MEMORY USED: %0.2f KB&, collectgarbage(&count&)))            CCTextureCache:sharedTextureCache():dumpCachedTextureInfo()            print(&----------------------------------------&)        end    endendfunction us._updateHandler(event, value)    updater.state = event    if event == &success& then        updater.stateValue = value:getCString()        updater.updateFinalResInfo()        if us._succHandler then            us._succHandler()        end    elseif event == &error& then        updater.stateValue = value:getCString()    elseif event == &progress& then        updater.stateValue = tostring(value:getValue())    elseif event == &state& then        updater.stateValue = value:getCString()    end    us._label:setString(updater.stateValue)    assert(event ~= &error&,         string.format(&Update error: %s !&, updater.stateValue))endfunction us.addListener(handler)    us._succHandler = handler    return usendfunction us.onEnter()    updater.update(us._updateHandler)endfunction us.onExit()    updater.clean()    us:unregisterScriptHandler()endfunction us.onCleanup()endus:registerScriptHandler(us._sceneHandler)us._addUI()return us代码都在上面,说重点:4.4.1 还是没有framework这是必须一直牢记的。由于没有载入quick的 framework,所有的quick特性都不能使用。你也许会说没有framework我怎么写界面?那么想想用C++的同学吧!那个代码怎么也比Lua多吧?display.newSprite(&res/pic/init_bg.png&)    :align(display.CENTER, display.cx, display.cy)    :addTo(self, 0)在没有quick framework的时候需要改成这样:local __bg = CCSprite:create(us._getres(&res/pic/init_bg.png&))display.align(__bg, display.CENTER, display.cx, display.cy)us:addChild(__bg, 0)等等!为啥我用了 display !!!魂淡,你不会偷quick的啊啊啊!4.4.2 必须要偷的代码为了方便使用,我们可以偷一部分framework的代码过来(干嘛说得那么难听嘛,程序员怎么能用偷?程序员的事,用CV啊),注意CV来的代码用local变量来保存。由于 updateScene 已经是一个可视的场景,因此quick中关于界面缩放设置的那部分代码也是必须CV过来。不多,几十行而已。游戏产品绝大多数都不会做成横屏竖屏自动适应的(自己找SHI啊有木有),因此界面缩放的代码我也只保存了一个横屏的,这又省了不少。那CV的同学,注意自己改啊!4.4.3 update.updateScene._getres(path)在 update.updateScene 模块中,所有涉及到资源路径的地方,必须使用这个方法来包裹。这个方法先从 update.updater 模块中获取最新的资源索引列表,然后根据我们传递的相对路径从索引列表中查找到资源的实际路径(可能是原包自带的资源,也可能是更新后的资源的绝对路径),然后载入它们。这能保证我们使用的是最新的资源。4.4.4 update.updateScene._updateHandler(event, value)这个方法已经在
讲过了。注意其中的 _succHandler 是在 update.UpdateApp 中定义的匿名函数。4.4.5 怎么使用这个模块如果你要使用这个模块,那么可能大部分都要重写。你可以看到,我在这个模块中只有一个背景图和一个 CCLabeTTF 来显示下载进度和状态。你当然不希望你的更新界面就是这个样子。怎么也得来个妹子做封面不是?[ 此帖被zong在 11:29重新编辑 ]
http://zengrong.net注册的时候手抖(jian)少输入一个字母,所以就这样了……
级别: 侠客
可可豆: 349 CB
威望: 268 点
在线时间: 67(时)
发自: Web Page
4.5 update.updater这是整个更新系统的核心部分了。代码更长一点,但其实很好懂。在这个模块中,我们需要完成下面的工作:调用C++的Updater模块来获取远程的版本号以及资源下载地址;调用C++的Updater模块来下载解压;合并解压后的新资源到新资源文件夹;更新总的资源索引;删除临时文件;报告更新中的各种错误。所以说,这是一个工具模块。它提供的是给更新使用的各种工具。而 UpdateApp 和 updateScene 则分别是功能和界面模块。--- The helper for update package.-- It can download resources and uncompress it, -- copy new package to res directory,-- and remove temporery directory.-- @author zrong(zengrong.net)-- Creation require &lfs&local updater = {}updater.STATES = {    kDownStart = &downloadStart&,    kDownDone = &downloadDone&,    kUncompressStart = &uncompressStart&,    kUncompressDone = &uncompressDone&,    unknown = &stateUnknown&,}updater.ERRORS = {    kCreateFile = &errorCreateFile&,    kNetwork = &errorNetwork&,    kNoNewVersion = &errorNoNewVersion&,    kUncompress = &errorUncompress&,    unknown = &errorUnknown&;}function updater.isState(state)    for k,v in pairs(updater.STATES) do        if v == state then            return true        end    end    return falseendfunction updater.clone(object)    local lookup_table = {}    local function _copy(object)        if type(object) ~= &table& then            return object        elseif lookup_table[object] then            return lookup_table[object]        end        local new_table = {}        lookup_table[object] = new_table        for key, value in pairs(object) do            new_table[_copy(key)] = _copy(value)        end        return setmetatable(new_table, getmetatable(object))    end    return _copy(object)endfunction updater.vardump(object, label, returnTable)    local lookupTable = {}    local result = {}    local function _v(v)        if type(v) == &string& then            v = &\&& .. v .. &\&&        end        return tostring(v)    end    local function _vardump(object, label, indent, nest)        label = label or &&        local postfix = &&        if nest & 1 then postfix = &,& end        if type(object) ~= &table& then            if type(label) == &string& then                result[#result +1] = string.format(&%s[\&%s\&] = %s%s&, indent, label, _v(object), postfix)            else                result[#result +1] = string.format(&%s%s%s&, indent, _v(object), postfix)            end        elseif not lookupTable[object] then            lookupTable[object] = true            if type(label) == &string& then                result[#result +1 ] = string.format(&%s%s = {&, indent, label)            else                result[#result +1 ] = string.format(&%s{&, indent)            end            local indent2 = indent .. &    &            local keys = {}            local values = {}            for k, v in pairs(object) do                keys[#keys + 1] = k                values[k] = v            end            table.sort(keys, function(a, b)                if type(a) == &number& and type(b) == &number& then                    return a & b                else                    return tostring(a) & tostring(b)                end            end)            for i, k in ipairs(keys) do                _vardump(values[k], k, indent2, nest + 1)            end            result[#result +1] = string.format(&%s}%s&, indent, postfix)        end    end    _vardump(object, label, &&, 1)    if returnTable then return result end    return table.concat(result, &\n&)endlocal u  = nillocal f = CCFileUtils:sharedFileUtils()-- The res index file in original package.local lresinfo = &res/resinfo.lua&local uroot = f:getWritablePath()-- The directory for save updated files.local ures = uroot..&res/&-- The package zip file what download from server.local uzip = uroot..&res.zip&-- The directory for uncompress res.zip.local utmp = uroot..&utmp/&-- The res index file in zip package for update.local zresinfo = utmp..&res/resinfo.lua&-- The res index file for final game.-- It combiled original lresinfo and zresinfo.local uresinfo = ures .. &resinfo.lua&local localResInfo = nillocal remoteResInfo = nillocal finalResInfo = nillocal function _initUpdater()    print(&initUpdater, &, u)    if not u then u = Updater:new() end    print(&after initUpdater:&, u)endfunction updater.writeFile(path, content, mode)    mode = mode or &w+b&    local file = io.open(path, mode)    if file then        if file:write(content) == nil then return false end        io.close(file)        return true    else        return false    endendfunction updater.readFile(path)    return f:getFileData(path)endfunction updater.exists(path)    return f:isFileExist(path)end--[[-- Departed, uses lfs instead.function updater._mkdir(path)    _initUpdater()    return u:createDirectory(path)end-- Departed, get a warning in ios simulatorfunction updater._rmdir(path)    _initUpdater()    return u:removeDirectory(path)end--]]function updater.mkdir(path)    if not updater.exists(path) then        return lfs.mkdir(path)    end    return trueendfunction updater.rmdir(path)    print(&updater.rmdir:&, path)    if updater.exists(path) then        local function _rmdir(path)            local iter, dir_obj = lfs.dir(path)            while true do                local dir = iter(dir_obj)                if dir == nil then break end                if dir ~= &.& and dir ~= &..& then                    local curDir = path..dir                    local mode = lfs.attributes(curDir, &mode&)                     if mode == &directory& then                        _rmdir(curDir..&/&)                    elseif mode == &file& then                        os.remove(curDir)                    end                end            end            local succ, des = os.remove(path)            if des then print(des) end            return succ        end        _rmdir(path)    end    return trueend-- Is there a update.zip package in ures directory?-- If it is true, return its abstract path.function updater.hasNewUpdatePackage()    local newUpdater = ures..&lib/update.zip&    if updater.exists(newUpdater) then        return newUpdater    end    return nilend-- Check local resinfo and remote resinfo, compare their version value.function updater.checkUpdate()    localResInfo = updater.getLocalResInfo()    local localVer = localResInfo.version    print(&localVer:&, localVer)    remoteResInfo = updater.getRemoteResInfo(localResInfo.update_url)    local remoteVer = remoteResInfo.version    print(&remoteVer:&, remoteVer)    return remoteVer ~= localVerend-- Copy resinfo.lua from original package to update directory(ures) -- when it is not in ures.function updater.getLocalResInfo()    print(string.format(&updater.getLocalResInfo, lresinfo:%s, uresinfo:%s&,         lresinfo,uresinfo))    local resInfoTxt = nil    if updater.exists(uresinfo) then        resInfoTxt = updater.readFile(uresinfo)    else        assert(updater.mkdir(ures), ures..& create error!&)        local info = updater.readFile(lresinfo)        print(&localResInfo:&, info)        assert(info, string.format(&Can not get the constent from %s!&, lresinfo))        updater.writeFile(uresinfo, info)        resInfoTxt = info    end    return assert(loadstring(resInfoTxt))()endfunction updater.getRemoteResInfo(path)    _initUpdater()    print(&updater.getRemoteResInfo:&, path)    local resInfoTxt = u:getUpdateInfo(path)    print(&resInfoTxt:&, resInfoTxt)    return assert(loadstring(resInfoTxt))()endfunction updater.update(handler)    assert(remoteResInfo and remoteResInfo.package, &Can not get remoteResInfo!&)    print(&updater.update:&, remoteResInfo.package)    if handler then        u:registerScriptHandler(handler)    end    updater.rmdir(utmp)    u:update(remoteResInfo.package, uzip, utmp, false)endfunction updater._copyNewFile(resInZip)    -- Create nonexistent directory in update res.    local i,j = 1,1    while true do        j = string.find(resInZip, &/&, i)        if j == nil then break end        local dir = string.sub(resInZip, 1,j)        -- Save created directory flag to a table because        -- the io operation is too slow.        if not updater._dirList[dir] then            updater._dirList[dir] = true            local fullUDir = uroot..dir            updater.mkdir(fullUDir)        end        i = j+1    end    local fullFileInURes = uroot..resInZip    local fullFileInUTmp = utmp..resInZip    print(string.format('copy %s to %s', fullFileInUTmp, fullFileInURes))    local zipFileContent = updater.readFile(fullFileInUTmp)    if zipFileContent then        updater.writeFile(fullFileInURes, zipFileContent)        return fullFileInURes    end    return nilendfunction updater._copyNewFilesBatch(resType, resInfoInZip)    local resList = resInfoInZip[resType]    if not resList then return end    local finalRes = finalResInfo[resType]    for __,v in ipairs(resList) do        local fullFileInURes = updater._copyNewFile(v)        if fullFileInURes then            -- Update key and file in the finalResInfo            -- Ignores the update package because it has been in memory.            if v ~= &res/lib/update.zip& then                finalRes[v] = fullFileInURes            end        else            print(string.format(&updater ERROR, copy file %s.&, v))        end    endendfunction updater.updateFinalResInfo()    assert(localResInfo and remoteResInfo,        &Perform updater.checkUpdate() first!&)    if not finalResInfo then        finalResInfo = updater.clone(localResInfo)    end    --do return end    local resInfoTxt = updater.readFile(zresinfo)    local zipResInfo = assert(loadstring(resInfoTxt))()    if zipResInfo[&version&] then        finalResInfo.version = zipResInfo[&version&]    end    -- Save a dir list maked.    updater._dirList = {}    updater._copyNewFilesBatch(&lib&, zipResInfo)    updater._copyNewFilesBatch(&oth&, zipResInfo)    -- Clean dir list.    updater._dirList = nil    updater.rmdir(utmp)    local dumpTable = updater.vardump(finalResInfo, &local data&, true)    dumpTable[#dumpTable+1] = &return data&    if updater.writeFile(uresinfo, table.concat(dumpTable, &\n&)) then        return true    end    print(string.format(&updater ERROR, write file %s.&, uresinfo))    return falseendfunction updater.getResCopy()    if finalResInfo then return updater.clone(finalResInfo) end    return updater.clone(localResInfo)endfunction updater.clean()    if u then        u:unregisterScriptHandler()        u:delete()        u = nil    end    updater.rmdir(utmp)    localResInfo = nil    remoteResInfo = nil    finalResInfo = nilendreturn updater什么什么?你说有CCB和CCS?CCS你妹啊!同学我和你不是一个班的。例如,原来在quick中这样写:代码都在上面,还是说重点:4.5.1 就是没有framework我嘴巴都说出茧子了,没有就是没有。不过,我又从quick CV了几个方法过来:clone 方法用来完全复制一个table,在复制文件索引列表的时候使用;vardump 方法用来1持久化索引列表,使其作为一个lua文件保存在设备存储器上。有修改。writeFile 和 readFile 用于把需要的文件写入设备中,也用它来复制文件(读入一个文件,在另一个地方写入来实现复制)exists 这个和quick实现的不太一样,直接用 CCFileUtils 了。4.5.2 文件操作除了可以用 writeFile 和 readFile 来实现文件的复制操作之外,还要实现文件夹的创建和删除。这个功能可以使用 lfs(Lua file system) 来实现,参见: 。4.5.3 相关目录和变量上面的代码中定义了几个变量,在这里进行介绍方便理解:4.5.3.1 lres(local res)安装包所带的res目录;4.5.3.2 ures(updated res)保存在设备上的res目录,用于保存从网上下载的新资源;4.5.3.3 utmp(update temp)临时文件夹,用于解压缩,更新后会删除;4.5.3.4 lresinfo(本地索引文件)安装包内自带的所有资源的索引文件,所有资源路径指向包内自带的资源。打包的时候和产品包一起提供,产品包会默认使用这个资源索引文件来查找资源。它的大概内容如下:&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&local data = {&&&&version = &1.0&,&&&&update_url = &http://192.168.18.22:8080/updater/resinfo.lua&,&&&&lib = {&&&&&&&&[&res/lib/config.zip&] = &res/lib/config.zip&,&&&&&&&&[&res/lib/framework_precompiled.zip&] = &res/lib/framework_precompiled.zip&,&&&&&&&&[&res/lib/root.zip&] = &res/lib/root.zip&,&&&&&&&&......&&&&},&&&&oth = {&&&&&&&&[&res/pic/init_bg.png&] = &res/pic/init_bg.png&,&&&&&&&&......&&&&},}return data&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&local data = {    version = &1.0&,    update_url = &http://192.168.18.22:8080/updater/resinfo.lua&,    lib = {        [&res/lib/config.zip&] = &res/lib/config.zip&,        [&res/lib/framework_precompiled.zip&] = &res/lib/framework_precompiled.zip&,        [&res/lib/root.zip&] = &res/lib/root.zip&,        ......    },    oth = {        [&res/pic/init_bg.png&] = &res/pic/init_bg.png&,        ......    },}return data从它的结构可以看出,它包含了当前包的版本(version)、在哪里获取要更新的资源索引文件(update_url)

我要回帖

更多关于 checkresupdate 的文章

 

随机推荐