https://blog.csdn.net/wskai1/article/details/59055534
稍等犬金,app會(huì)安裝到手機(jī)或者模擬器.
- 現(xiàn)在打開 TestProject/www/
index.html
, 做一些改動(dòng)然后保存. 幾秒種后你可以在手機(jī)或模擬器上看到更新后的頁(yè)面.
到此,你可以本地開發(fā)垄懂,新的web內(nèi)容會(huì)自動(dòng)在設(shè)備上更新蛛倦,而無(wú)需重新啟動(dòng)app查看效果.
更新機(jī)制的流程圖
先防止所有的配置相關(guān)的內(nèi)容弄得你稀里糊涂 - 先來(lái)看看此插件的實(shí)現(xiàn)更新功能的流程圖. 應(yīng)該沒有技術(shù)細(xì)節(jié).
用戶打開你的app.
插件初始化浑玛,在后臺(tái)進(jìn)程啟動(dòng) 升級(jí)加載器(update loader).
Update loader 從
config.xml
取config-file
配置(一個(gè)url)憎亚,并從此url加載一段 JSON 配置. 然后它把這段JSON配置中的release
版本號(hào) 和當(dāng)前app 已經(jīng)安裝的進(jìn)行比較. 如果不同 - 進(jìn)入下一步.Update loader 使用app配置(application config)中的
content_url
衙耕,去加載清單文件(manifest). 它會(huì)找出自上次升級(jí)以來(lái)刃泌,哪些文件需要更新.Update loader 從
content_url
下載更新文件.如果一切順利 - 發(fā)出一個(gè)"升級(jí)文件已經(jīng)準(zhǔn)備好凡壤,可以安裝了"的通知.
升級(jí)文件已安裝, app重新進(jìn)入更新過(guò)的頁(yè)面.
當(dāng)然, 還有其他的細(xì)節(jié), 不過(guò)你已經(jīng)有了大致的思路.
web內(nèi)容是如何存儲(chǔ)和更新的
每一個(gè)Cordova 項(xiàng)目都有一個(gè) www
目錄, 這里存放所有的web內(nèi)容. 當(dāng)cordova build
執(zhí)行后 - www
里的內(nèi)容會(huì)拷貝到對(duì)應(yīng)platform的 www
目錄下:
安卓:
platforms/android/assets/www
.iOS:
platforms/ios/www
.
于是這些文件被打包進(jìn)了app. 我們不能更新安裝包里的這些文件, 因?yàn)樗鼈兪侵蛔x的. 正因?yàn)槿绱耍晕覀円赼pp第一次啟動(dòng)的時(shí)候耙替,將內(nèi)置的web內(nèi)容(www目錄)復(fù)制到外部存儲(chǔ). 我們不想在拷貝過(guò)程中阻塞ui - 我們還是會(huì)先加載app內(nèi)置的index.html. 但是下一次啟動(dòng)或更新 - 我們就從外部存儲(chǔ)加載index.html.
但是如果你的app外殼需要增加新的cordova插件或者原生功能 - 你必須要重新上架外殼app到store商店. 還有 - 增加外殼 app 的build版本號(hào) (App Store 或 Google Play強(qiáng)制的).下次啟動(dòng)亚侠,插件檢查外殼app版本號(hào)是否變化, 如果變了 - 會(huì)重新拷貝內(nèi)置web內(nèi)容(www目錄)到外部存儲(chǔ).
開發(fā)app的時(shí)候 - 你可能會(huì)困惑: 改了一些文件, 重新啟動(dòng)了app - 但卻看到的是舊的頁(yè)面. 現(xiàn)在你知道原因了: 插件用的是舊版本的web內(nèi)容(外部存儲(chǔ)中). 若要清除緩存,你需要:
卸載app, 執(zhí)行
cordova run
.增加外殼app版本號(hào)俗扇,強(qiáng)制插件重新安裝
www
目錄. 更改外殼app版本號(hào)請(qǐng)?jiān)O(shè)置config.xml文件的
android-versionCode
和ios-CFBundleVersion
.安裝 本地開發(fā)擴(kuò)展 硝烂,讓它幫你處理版本號(hào)問(wèn)題. 每次build他會(huì)自動(dòng)幫你app的build版本號(hào)加1,不需要你手動(dòng)更改
上面就是簡(jiǎn)要介紹, 以便你理解大致的思路. 現(xiàn)在我們繼續(xù)深入.
之后你會(huì)閱讀到 配置文件 這一節(jié)- 這有app配置 (application config), 名字是chcp.json
. 里面有個(gè) release
設(shè)置, 這個(gè)指明了web內(nèi)容的版本. 這個(gè)配置必須而且每次發(fā)布的release版本必須不一樣. 它由 命令行客戶端 自動(dòng)生成狐援,格式是: yyyy.MM.dd-HH.mm.ss
(比如 2015.09.01-13.30.35
).
每次發(fā)布钢坦,插件在外部存儲(chǔ)自動(dòng)生成一個(gè)以這個(gè) release版本 為名字的目錄, 然后把web內(nèi)容全部放到這里面. release版本號(hào)成為了 url的一部分. 這個(gè)手段可以解決一些問(wèn)題:
網(wǎng)頁(yè)內(nèi)容緩存問(wèn)題. 比如, iOS 上,css 文件會(huì)被 UIWebView緩存起來(lái), 即使我們重新載入了index.html - 新的樣式還是不會(huì)被應(yīng)用. 你需要用任務(wù)管理器殺死app, 或者改變css的路徑.
基本不會(huì)發(fā)生更新后損壞已有web內(nèi)容的現(xiàn)象, 因?yàn)槲覀兠看胃露荚诓煌哪夸浵?
即使更新導(dǎo)致了web內(nèi)容損壞 - 我們可以回滾到上一個(gè)版本的release.
比如, 我們當(dāng)前運(yùn)行的release版本是 2015.12.01-12.01.33
. 這意味著:
所有web內(nèi)容存儲(chǔ)在
/sdcard/some_path/2015.12.01-12.01.33/www/
. 包含了Cordova的資源.Index 頁(yè)面, 用戶看到的是
/sdcard/some_path/2015.12.01-12.01.33/www/index.html
.
某個(gè)時(shí)候我們發(fā)布了一個(gè)新的release: 2016.01.03-10.45.01
. 第一步啥酱,插件需要下載新的web文件, 發(fā)生情況如下:
在外部存儲(chǔ)創(chuàng)建了一個(gè)以新的 release 版本號(hào)為名字的目錄:
/sdcard/some_path/2016.01.03-10.45.01/
.目錄里面 - 又創(chuàng)建了一個(gè)
update
目錄 :/sdcard/some_path/2016.01.03-10.45.01/update/
.所有根據(jù)
chcp.manifest
更新的文件 都被下載到了這個(gè)update
目錄內(nèi).新的
chcp.manifest
和chcp.json
也被放到了update
目錄內(nèi).新的web內(nèi)容已準(zhǔn)備安裝.
安裝更新的時(shí)候:
插件從當(dāng)前正在使用的release版本 目錄內(nèi)拷貝
www
下所有內(nèi)容到 新的 release 版本目錄下. 用我們的例子就是:從/sdcard/some_path/2015.12.01-12.01.33/www/
拷貝所有文件到/sdcard/some_path/2016.01.03-10.45.01/www/
.從
update
目錄下拷貝新的web內(nèi)容和配置文件爹凹,到www
目錄下:/sdcard/some_path/2016.01.03-10.45.01/update/
->/sdcard/some_path/2016.01.03-10.45.01/www/
.移除
/sdcard/some_path/2016.01.03-10.45.01/update/
目錄,因?yàn)槲覀儾辉偈褂昧?加載新的release版本index.html:
/sdcard/some_path/2016.01.03-10.45.01/www/index.html
.
至此镶殷,插件會(huì)從新的release加載頁(yè)面, 而舊的release則會(huì)作為一個(gè)備份留下來(lái)禾酱,以防萬(wàn)一.
Cordova Hot Code Push 命令行客戶端
Cordova Hot Code Push 命令行客戶端 是一個(gè)命令行工具,以便你web內(nèi)容的開發(fā).
它可以:
生成
chcp.json
和chcp.manifest
文件, 這樣你就不用手動(dòng)去創(chuàng)建;運(yùn)行本地服務(wù)绘趋,開發(fā)時(shí)可以檢測(cè)更新颤陶,并發(fā)布新的release版本,使得可以再設(shè)備上實(shí)時(shí)更新web內(nèi)容;
部署你的web內(nèi)容到外部服務(wù)器上.
當(dāng)然, 你可以不使用這個(gè)命令行工具. 只是用了它會(huì)更方便一些.
本地開發(fā)擴(kuò)展
當(dāng)你本地開發(fā)app時(shí) - 一般做法類似:
web項(xiàng)目做一些更改.
執(zhí)行
cordova run
啟動(dòng)app.稍等一會(huì)查看運(yùn)行結(jié)果.
即使很小的變更也需要打包重裝app. 耗時(shí)比較久陷遮,比較麻煩.
為了提升速度 - 你可以使用本地開發(fā)擴(kuò)展 Hot Code Push Local Development Add-on. 安裝很簡(jiǎn)答:
添加此cordova插件.
啟動(dòng)本地服務(wù)
cordova-hcp server
.在你的項(xiàng)目的
config.xml
文件中<chcp />
塊下添加<local-development enabled="true" />
.啟動(dòng)app.
這樣, 所有web內(nèi)容的變更都會(huì)被插件檢測(cè)到, 并直接更新顯示到app上滓走,而不需要重啟app.
只有在添加了新的cordova插件時(shí)你才會(huì)重啟app.
重要: 你應(yīng)該只在開發(fā)狀態(tài)下使用此擴(kuò)展. 發(fā)布外殼app的時(shí)候,應(yīng)該移除此擴(kuò)展: cordova plugin remove cordova-hot-code-push-local-dev-addon
.
Cordova 配置項(xiàng)
你應(yīng)該知道, Cordova 使用 config.xml
文件配置不同項(xiàng)目: app名字, 描述, 起始頁(yè)面帽馋,等等. 使用config.xml文件搅方,你也可以為此插件配置.
這些配置位于 <chcp>
塊. 比如:
<pre style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 16px; position: relative; font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace; white-space: pre-wrap; overflow-wrap: normal; overflow: auto; font-size: 13.6px; line-height: 1.45; color: rgb(0, 0, 0); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial; word-break: normal; background-color: rgb(247, 247, 247);"><chcp>
<config-file url="https://5027caf9.ngrok.com/chcp.json"/>
</chcp></pre>
config-file
定義了一個(gè) URL比吭,指定了需要從哪里加載app配置(application config,就是chcp.json). URL 在 url
屬性中聲明. 此項(xiàng)必須.
以防萬(wàn)一姨涡,開發(fā)的時(shí)候, 如果 config-file
沒有定義 - 會(huì)自動(dòng)設(shè)為本地服務(wù)上 chcp.json 的路徑.
auto-download
自動(dòng)下載web內(nèi)容更新. 默認(rèn)是自動(dòng), 如果你想手動(dòng)下載web內(nèi)容更新衩藤,你可以使用 JavaScript 模塊(下面有).
禁用自動(dòng)下載可以設(shè)置 config.xml
:
<pre style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 16px; position: relative; font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace; white-space: pre-wrap; overflow-wrap: normal; overflow: auto; font-size: 13.6px; line-height: 1.45; color: rgb(0, 0, 0); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial; word-break: normal; background-color: rgb(247, 247, 247);"><chcp>
<auto-download enabled="false" />
</chcp></pre>
默認(rèn)是 true
.
auto-install
自動(dòng)安裝. web內(nèi)容更新. 默認(rèn)是自動(dòng), 如果你想手動(dòng)安裝web內(nèi)容更新,你可以使用 JavaScript 模塊(下面有).
禁用自動(dòng)安裝可以設(shè)置 config.xml
:
<pre style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 16px; position: relative; font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace; white-space: pre-wrap; overflow-wrap: normal; overflow: auto; font-size: 13.6px; line-height: 1.45; color: rgb(0, 0, 0); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial; word-break: normal; background-color: rgb(247, 247, 247);"><chcp>
<auto-install enabled="false" />
</chcp></pre>
默認(rèn)是 true
.
配置文件
此插件用到2個(gè)配置文件:
app配置 Application config - 包含最新的release信息: release 版本號(hào), 最低需要的外殼app版本號(hào)涛漂,等等. 文件名 chcp.json
Web內(nèi)容清單 Content manifest - 包含所有web內(nèi)容文件的名字和MD5值. 文件名 chcp.manifest
這兩個(gè)文件必須. 他們描述了是否有新的release版本赏表,以及文件更新時(shí)的比較.
還有一個(gè)build 可選參數(shù) (build options) 文件, 可以再執(zhí)行cordova build
命令時(shí)指定插件的配置.
Application config app配置
包含最新版本的release信息.
簡(jiǎn)單的例子:
<pre style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 16px; position: relative; font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace; white-space: pre-wrap; overflow-wrap: normal; overflow: auto; font-size: 13.6px; line-height: 1.45; color: rgb(0, 0, 0); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial; word-break: normal; background-color: rgb(247, 247, 247);">{ "content_url": "https://5027caf9.ngrok.com", "release": "2015.09.01-13.30.35"}</pre>
這個(gè)文件應(yīng)該放在 www
目錄下匈仗,文件名是 chcp.json
. 這個(gè)文件也被打包到了外殼app內(nèi).
你可以手動(dòng)創(chuàng)建它, 或者用 cordova-hcp
命令(Cordova Hot Code Push 命令行)自動(dòng)生成. 只要在cordova項(xiàng)目根目錄下運(yùn)行 cordova-hcp init
, 以后要發(fā)布新的release只要執(zhí)行 cordova-hcp build
. 更多內(nèi)容請(qǐng)閱讀 命令行客戶端的文檔.
content_url
服務(wù)端URL, 也就是你所有web內(nèi)容文件的位置. 插件會(huì)把它作為下載新的清單文件瓢剿、新的web內(nèi)容文件的 base url. 此項(xiàng)必須.
release
任何字符串. 每次release應(yīng)該唯一. 插件基于這個(gè)才知道有沒有新版本release. 此項(xiàng)必須.
重要: 插件只比較release字符串是否相等, 如果不等,就認(rèn)為服務(wù)端有新版本.(不會(huì)比較大忻小)
min_native_interface
所需最小的外殼app版本. 這是app的build版本號(hào)跋选,是個(gè)整型數(shù)字, 不是應(yīng)用商店中看到的形如"1.0.0"字符串.
在 config.xml
中,這樣指定build版本號(hào):
<pre style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 16px; position: relative; font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace; white-space: pre-wrap; overflow-wrap: normal; overflow: auto; font-size: 13.6px; line-height: 1.45; color: rgb(0, 0, 0); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial; word-break: normal; background-color: rgb(247, 247, 247);"><widget id="io.cordova.hellocordova"
version="1.0.1"
android-versionCode="7"
ios-CFBundleVersion="3"></pre>
version
- app字符串版本號(hào), 也就是用戶在商店中看到的版本.android-versionCode
- 安卓的build版本號(hào). 這個(gè)應(yīng)該用于min_native_interface
.ios-CFBundleVersion
- iOS的build版本號(hào).這個(gè)應(yīng)該用于min_native_interface
.
Preference creates dependency between the web and the native versions of the application.
重要: 因?yàn)?a target="_blank" rel="nofollow">cordova的一個(gè)奇葩現(xiàn)象, 生成的 .apk
的build版本號(hào)會(huì)被加 10, 導(dǎo)致了變成了形如 70, 72, or 74, 根據(jù)不同平臺(tái) (arm/x86/etc)哗蜈,后面的0前标、2、4不一樣. 為了繞過(guò)這個(gè), 我們建議也給 iOS build版本號(hào)手動(dòng)加10, 這樣 min_native_interface
(比如 70
) 就可以對(duì)安卓和iOS都有效, 大致是這樣:
<pre style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 16px; position: relative; font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace; white-space: pre-wrap; overflow-wrap: normal; overflow: auto; font-size: 13.6px; line-height: 1.45; color: rgb(0, 0, 0); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial; word-break: normal; background-color: rgb(247, 247, 247);"><widget id="io.cordova.hellocordova"
version="1.0.1"
android-versionCode="7"
ios-CFBundleVersion="70"></pre>
舉個(gè)例子, 假設(shè)你的外殼app加了個(gè)新的插件 - 你應(yīng)該會(huì)更新外殼app. 為了防止用戶下載了不適合他現(xiàn)有外殼app的web內(nèi)容 - 你應(yīng)該設(shè)置 min_native_interface
這個(gè)值.
比如, 我們app里的chcp.json是這樣的:
<pre style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 16px; position: relative; font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace; white-space: pre-wrap; overflow-wrap: normal; overflow: auto; font-size: 13.6px; line-height: 1.45; color: rgb(0, 0, 0); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial; word-break: normal; background-color: rgb(247, 247, 247);">{ "content_url": "https://5027caf9.ngrok.com", "release": "2015.09.01-13.30.35", "min_native_interface": 10}</pre>
外殼app的build版本是 13
.
某個(gè)時(shí)候距潘,web內(nèi)容有了新的release發(fā)布:
<pre style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 16px; position: relative; font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace; white-space: pre-wrap; overflow-wrap: normal; overflow: auto; font-size: 13.6px; line-height: 1.45; color: rgb(0, 0, 0); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial; word-break: normal; background-color: rgb(247, 247, 247);">{ "content_url": "https://5027caf9.ngrok.com", "release": "2015.09.05-12.20.15", "min_native_interface": 15}</pre>
插件加載到這段json的時(shí)候, 發(fā)現(xiàn) min_native_interface
比當(dāng)前外殼app的build號(hào)要大 - 它就不會(huì)下載web內(nèi)容. 而是觸發(fā)一個(gè) chcp_updateLoadFailed
錯(cuò)誤通知, 告訴用戶需要升級(jí)外殼app了. 更多內(nèi)容請(qǐng)看 從應(yīng)用商店請(qǐng)求app升級(jí) 小節(jié).
備注: 目前你還不能為不同平臺(tái)指定不同的 min_native_interface
. 如果需要以后可以支持.
update
指定了什么時(shí)候安裝web內(nèi)容更新. 支持的值有:
start
- app啟動(dòng)時(shí)安裝更新. 默認(rèn)值.resume
- app從后臺(tái)切換過(guò)來(lái)的時(shí)候安裝更新.now
- web內(nèi)容下載完畢即安裝更新.
你可以用JavaScript禁止自動(dòng)安裝. 請(qǐng)看 JavaScript module 小節(jié).
android_identifier
apk包名. 如果指定了 - 引導(dǎo)用戶到 Google Play Store 的app頁(yè)面.
ios_identifier
ios應(yīng)用標(biāo)識(shí)號(hào), 比如: id345038631
. 如果指定了 - 引導(dǎo)用戶到 App Store 的app頁(yè)面.
Content manifest內(nèi)容清單
內(nèi)容清單描述了web項(xiàng)目所有文件的狀態(tài).
<pre style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 16px; position: relative; font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace; white-space: pre-wrap; overflow-wrap: normal; overflow: auto; font-size: 13.6px; line-height: 1.45; color: rgb(0, 0, 0); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial; word-break: normal; background-color: rgb(247, 247, 247);">[
{ "file": "index.html", "hash": "5540bd44cbcb967efef932bc8381f886"
},
{ "file": "css/index.css", "hash": "e46d9a1c456a9c913ca10f3c16d50000"
},
{ "file": "img/logo.png", "hash": "7e34c95ac701f8cd9f793586b9df2156"
},
{ "file": "js/index.js", "hash": "0ba83df8459288fd1fa1576465163ff5"
}
]</pre>
根據(jù)它炼列,插件才知道什么文件被移除了, 什么文件更新或新增了. 于是:
更新階段,從服務(wù)端下載所有web內(nèi)容文件;
安裝階段音比,刪除服務(wù)端不存在(已移除)的文件.
這個(gè)文件應(yīng)該放在 www
目錄下俭尖,文件名是 chcp.manifest
.這個(gè)文件也被打包到了外殼app內(nèi).
同樣的, 清單文件要放到 content_url
(app配置 Application config中指定的)指定的目錄下. 比如, 如果你的 content_url
是 https://somedomain.com/www
, 這個(gè)清單文件的url就必須是 https://somedomain.com/www/chcp.manifest
.
生成 chcp.manifest
文件可以執(zhí)行命令行客戶端的 build
命令 (在cordova項(xiàng)目根目錄下執(zhí)行):
<pre style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 16px; position: relative; font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace; white-space: pre-wrap; overflow-wrap: normal; overflow: auto; font-size: 13.6px; line-height: 1.45; color: rgb(0, 0, 0); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial; word-break: normal; background-color: rgb(247, 247, 247);">cordova-hcp build</pre>
file
相對(duì)于 www
的路徑(就是你存放web內(nèi)容的地方).
比如, 你的web內(nèi)容位于: /Workspace/Cordova/TestProject/www.
你的 file
值應(yīng)該是相對(duì)于這個(gè)路徑.
hash
文件的 MD5 值. 用于檢測(cè)自上次release以來(lái)。這個(gè)文件是否變更過(guò). 還有用于檢測(cè)app端下載的文件是否出錯(cuò).
建議: 每次變更web內(nèi)容后都應(yīng)該更新 chcp.manifest
文件. 否則插件不會(huì)檢測(cè)到任何更新.
Build options build設(shè)置
就像在 Cordova 配置項(xiàng) 一節(jié)中說(shuō)的 - 你可以在config.xml
文件里改變插件配置.
但是如果你想在使用build命令行的時(shí)候改變插件配置呢? 為了達(dá)到這個(gè)目的洞翩,你需要使用chcpbuild.options
文件.
文件必須位于 Cordova 項(xiàng)目根目錄. 在這個(gè)文件里面稽犁,你指定(JSON格式) 所有你想改變 config.xml
文件的配置. 源文件 config.xml
(Cordova項(xiàng)目根目錄) 不會(huì)發(fā)生變動(dòng), 我們改變的是 特定平臺(tái)下的 config.xml
(在cordova build過(guò)程的 after_prepare
階段).
比如, 你的Cordova項(xiàng)目是 /Cordova/TestProject
目錄.config.xml
文件 (/Cordova/TestProject/config.xml
) 有下面的配置:
<pre style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 16px; position: relative; font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace; white-space: pre-wrap; overflow-wrap: normal; overflow: auto; font-size: 13.6px; line-height: 1.45; color: rgb(0, 0, 0); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial; word-break: normal; background-color: rgb(247, 247, 247);"><chcp>
<config-file url="https://company_server.com/mobile/www/chcp.json" />
</chcp></pre>
這時(shí)我們?cè)?/Cordova/Testproject/
下創(chuàng)建 chcpbuild.options
文件,文件內(nèi)容如下:
<pre style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 16px; position: relative; font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace; white-space: pre-wrap; overflow-wrap: normal; overflow: auto; font-size: 13.6px; line-height: 1.45; color: rgb(0, 0, 0); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial; word-break: normal; background-color: rgb(247, 247, 247);">{
"dev": {
"config-file": "https://dev.company_server.com/mobile/www/chcp.json"
},
"production": {
"config-file": "https://company_server.com/mobile/www/chcp.json"
},
"QA": {
"config-file": "https://test.company_server.com/mobile/www/chcp.json"
}
}</pre>
build app的時(shí)候, 轉(zhuǎn)為開發(fā)要用的服務(wù)器, 可執(zhí)行:
<pre style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 16px; position: relative; font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace; white-space: pre-wrap; overflow-wrap: normal; overflow: auto; font-size: 13.6px; line-height: 1.45; color: rgb(0, 0, 0); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial; word-break: normal; background-color: rgb(247, 247, 247);">cordova build -- chcp-dev</pre>
結(jié)果就是, 特定拍下的 config.xml
文件(比如, /Cordova/TestProject/platforms/android/res/xml/config.xml
) 變成了這樣:
<pre style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 16px; position: relative; font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace; white-space: pre-wrap; overflow-wrap: normal; overflow: auto; font-size: 13.6px; line-height: 1.45; color: rgb(0, 0, 0); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial; word-break: normal; background-color: rgb(247, 247, 247);"><chcp>
<config-file url="https://dev.company_server.com/mobile/www/chcp.json"/>
</chcp></pre>
你可能注意到了 - 我們用的命令有個(gè) chcp-
. 這個(gè)必須, 這樣插件才知道, 這個(gè)參數(shù)是為它設(shè)置的. 而且, 不會(huì)和其它插件的命令參數(shù)沖突.
如果你的app可以測(cè)試了 - 你可以用下面的命令build, 就指定了測(cè)試服務(wù)器:
<pre style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 16px; position: relative; font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace; white-space: pre-wrap; overflow-wrap: normal; overflow: auto; font-size: 13.6px; line-height: 1.45; color: rgb(0, 0, 0); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial; word-break: normal; background-color: rgb(247, 247, 247);">cordova build -- chcp-QA</pre>
特定平臺(tái)下的 config.xml
就會(huì)變成:
<pre style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 16px; position: relative; font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace; white-space: pre-wrap; overflow-wrap: normal; overflow: auto; font-size: 13.6px; line-height: 1.45; color: rgb(0, 0, 0); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial; word-break: normal; background-color: rgb(247, 247, 247);"><chcp>
<config-file url="https://test.company_server.com/mobile/www/chcp.json"/>
</chcp></pre>
當(dāng)我們需要上架app的時(shí)候 (Google Play, App Store) - 我們正常build:
<pre style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 16px; position: relative; font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace; white-space: pre-wrap; overflow-wrap: normal; overflow: auto; font-size: 13.6px; line-height: 1.45; color: rgb(0, 0, 0); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial; word-break: normal; background-color: rgb(247, 247, 247);">cordova build --release</pre>
這樣 config.xml
是不會(huì)改變的.
如果沒有使用 chcpbuild.options
- 插件會(huì)使用 config.xml
里面默認(rèn)的值.
JavaScript 模塊
默認(rèn)情況下, 所有的 檢查更新->下載->安裝 過(guò)程都是插件在原生端自動(dòng)進(jìn)行的. 不需要其它js端代碼. 然而, 這些過(guò)程也可以用js控制.
你可以:
監(jiān)聽更新相關(guān)的事件;
從服務(wù)端檢查和下載新的web內(nèi)容;
安裝已下載的web內(nèi)容;
更改插件配置;
讓用戶到應(yīng)用商店下載新的外殼app.
監(jiān)聽更新事件
比如, web內(nèi)容已經(jīng)下載并可以安裝了骚亿,會(huì)有事件通知, 或者出錯(cuò)了導(dǎo)致安裝新的web內(nèi)容失敗了.
監(jiān)聽事件像這樣:
<pre style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 16px; position: relative; font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace; white-space: pre-wrap; overflow-wrap: normal; overflow: auto; font-size: 13.6px; line-height: 1.45; color: rgb(0, 0, 0); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial; word-break: normal; background-color: rgb(247, 247, 247);"> document.addEventListener(eventName, eventCallback, false);
function eventCallback(eventData) {
// do something
}</pre>
錯(cuò)誤事件有詳細(xì)錯(cuò)誤信息. 像這樣:
<pre style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 16px; position: relative; font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace; white-space: pre-wrap; overflow-wrap: normal; overflow: auto; font-size: 13.6px; line-height: 1.45; color: rgb(0, 0, 0); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial; word-break: normal; background-color: rgb(247, 247, 247);">function eventCallback(eventData) {
var error = eventData.details.error;
if (error) {
console.log('Error with code: ' + error.code);
console.log('Description: ' + error.description);
}
}</pre>
可用的事件如下:
chcp_updateIsReadyToInstall
- web內(nèi)容已經(jīng)下載并可以安裝時(shí)觸發(fā).chcp_updateLoadFailed
- 插件無(wú)法下載web更新時(shí)觸發(fā). 詳細(xì)錯(cuò)誤信息在事件參數(shù)里.chcp_nothingToUpdate
- 無(wú)可用更新下載時(shí)觸發(fā).chcp_updateInstalled
- web內(nèi)容安裝成功時(shí)觸發(fā).chcp_updateInstallFailed
- web內(nèi)容安裝失敗時(shí)觸發(fā). 詳細(xì)錯(cuò)誤信息在事件參數(shù)里.chcp_nothingToInstall
-無(wú)可用更新安裝時(shí)觸發(fā).chcp_assetsInstalledOnExternalStorage
- 插件成功把a(bǔ)pp內(nèi)置的web內(nèi)容拷貝到外置存儲(chǔ)中時(shí)觸發(fā). 你可能需要開發(fā)調(diào)試時(shí)用到這個(gè)事件已亥,也許不會(huì).chcp_assetsInstallationError
-插件無(wú)法拷貝app內(nèi)置的web內(nèi)容到外置存儲(chǔ)中時(shí)觸發(fā). 如果此事件發(fā)生了 - 插件不再工作. 也許是設(shè)備沒有足夠的存儲(chǔ)空間導(dǎo)致. 詳細(xì)錯(cuò)誤信息在事件參數(shù)里.
該舉一些簡(jiǎn)單的例子了. 假設(shè)我們有個(gè) index.js
文件, 它被 index.html
引用.
<pre style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 16px; position: relative; font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace; white-space: pre-wrap; overflow-wrap: normal; overflow: auto; font-size: 13.6px; line-height: 1.45; color: rgb(0, 0, 0); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial; word-break: normal; background-color: rgb(247, 247, 247);">var app = {
// Application Constructor
initialize: function() {
this.bindEvents();
},
// Bind any events that are required.
// Usually you should subscribe on 'deviceready' event to know, when you can start calling cordova modules
bindEvents: function() {
document.addEventListener('deviceready', this.onDeviceReady, false);
},
// deviceready Event Handler
onDeviceReady: function() {
console.log('Device is ready for work');
}
};
app.initialize();</pre>
這個(gè)和cordova默認(rèn)創(chuàng)建的 index.js
文件很像. 監(jiān)聽 chcp_updateIsReadyToInstall
事件如下:
<pre style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 16px; position: relative; font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace; white-space: pre-wrap; overflow-wrap: normal; overflow: auto; font-size: 13.6px; line-height: 1.45; color: rgb(0, 0, 0); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial; word-break: normal; background-color: rgb(247, 247, 247);">bindEvents: function() {
// ...some other events subscription code...
document.addEventListener('chcp_updateIsReadyToInstall', this.onUpdateReady, false);
},</pre>
編寫事件處理函數(shù):
<pre style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 16px; position: relative; font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace; white-space: pre-wrap; overflow-wrap: normal; overflow: auto; font-size: 13.6px; line-height: 1.45; color: rgb(0, 0, 0); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial; word-break: normal; background-color: rgb(247, 247, 247);">// chcp_updateIsReadyToInstall Event Handler
onUpdateReady: function() {
console.log('Update is ready for installation');
}</pre>
index.js
結(jié)果如下:
<pre style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 16px; position: relative; font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace; white-space: pre-wrap; overflow-wrap: normal; overflow: auto; font-size: 13.6px; line-height: 1.45; color: rgb(0, 0, 0); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial; word-break: normal; background-color: rgb(247, 247, 247);">var app = {
// Application Constructor
initialize: function() {
this.bindEvents();
},
// Bind any events that are required.
// Usually you should subscribe on 'deviceready' event to know, when you can start calling cordova modules
bindEvents: function() {
document.addEventListener('deviceready', this.onDeviceReady, false);
document.addEventListener('chcp_updateIsReadyToInstall', this.onUpdateReady, false);
},
// deviceready Event Handler
onDeviceReady: function() {
console.log('Device is ready for work');
},
// chcp_updateIsReadyToInstall Event Handler
onUpdateReady: function() {
console.log('Update is ready for installation');
}
};
app.initialize();</pre>
這樣我們就知道了web內(nèi)容什么時(shí)候下載完畢并可以安裝了. 通過(guò) JavaScript 模塊我們可以讓插件即時(shí)安裝web更新, 否則將在下次啟動(dòng)app時(shí)安裝.
檢查更新
使用js代碼,讓插件檢查更新:
<pre style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 16px; position: relative; font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace; white-space: pre-wrap; overflow-wrap: normal; overflow: auto; font-size: 13.6px; line-height: 1.45; color: rgb(0, 0, 0); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial; word-break: normal; background-color: rgb(247, 247, 247);">chcp.fetchUpdate(updateCallback);
function updateCallback(error, data) {
// do some work
}</pre>
回調(diào)有2個(gè)參數(shù):
error
- 如果檢查失敗来屠,有error參數(shù);null
表示一切正常;data
- 額外的 數(shù)據(jù), 原生端提供. 暫時(shí)可以忽略.
我們假設(shè) index.html
有一些按鈕, 按下它可以檢查更新. 我們需要這樣寫代碼:
監(jiān)聽button的
click
事件.當(dāng)點(diǎn)擊button時(shí)調(diào)用
chcp.fetchUpdate()
.處理更新事件的結(jié)果.
我們來(lái)改 index.js
代碼:
<pre style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 16px; position: relative; font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace; white-space: pre-wrap; overflow-wrap: normal; overflow: auto; font-size: 13.6px; line-height: 1.45; color: rgb(0, 0, 0); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial; word-break: normal; background-color: rgb(247, 247, 247);">var app = {
// Application Constructor
initialize: function() {
this.bindEvents();
},
// Bind any events that are required.
// Usually you should subscribe on 'deviceready' event to know, when you can start calling cordova modules
bindEvents: function() {
document.addEventListener('deviceready', this.onDeviceReady, false);
},
// deviceready Event Handler
onDeviceReady: function() {
// Add click event listener for our update button.
// We do this here, because at this point Cordova modules are initialized.
// Before that chcp is undefined.
document.getElementById('myFetchBtn').addEventListener('click', app.checkForUpdate);
},
checkForUpdate: function() {
chcp.fetchUpdate(this.fetchUpdateCallback);
},
fetchUpdateCallback: function(error, data) {
if (error) {
console.log('Failed to load the update with error code: ' + error.code);
console.log(error.description);
} else {
console.log('Update is loaded');
}
}
};
app.initialize();</pre>
注意: 即使你在fetchUpdate
回調(diào)里處理了虑椎,相關(guān)的更新事件還是會(huì)觸發(fā)并廣播的.
安裝web更新
調(diào)用:
<pre style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 16px; position: relative; font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace; white-space: pre-wrap; overflow-wrap: normal; overflow: auto; font-size: 13.6px; line-height: 1.45; color: rgb(0, 0, 0); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial; word-break: normal; background-color: rgb(247, 247, 247);">chcp.installUpdate(installationCallback);
function installationCallback(error) {
// do some work
}</pre>
如果安裝失敗 - error
參數(shù)會(huì)有錯(cuò)誤詳細(xì)信息. 否則- 為 null
.
現(xiàn)在讓我們來(lái)繼續(xù)上面的代碼,處理web內(nèi)容下載完后的安裝.
<pre style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 16px; position: relative; font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace; white-space: pre-wrap; overflow-wrap: normal; overflow: auto; font-size: 13.6px; line-height: 1.45; color: rgb(0, 0, 0); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial; word-break: normal; background-color: rgb(247, 247, 247);">var app = {
// Application Constructor
initialize: function() {
this.bindEvents();
},
// Bind any events that are required.
// Usually you should subscribe on 'deviceready' event to know, when you can start calling cordova modules
bindEvents: function() {
document.addEventListener('deviceready', this.onDeviceReady, false);
},
// deviceready Event Handler
onDeviceReady: function() {
// Add click event listener for our update button.
// We do this here, because at this point Cordova modules are initialized.
// Before that chcp is undefined.
document.getElementById('myFetchBtn').addEventListener('click', app.checkForUpdate);
},
checkForUpdate: function() {
chcp.fetchUpdate(this.fetchUpdateCallback);
},
fetchUpdateCallback: function(error, data) {
if (error) {
console.log('Failed to load the update with error code: ' + error.code);
console.log(error.description);
return;
}
console.log('Update is loaded, running the installation');
chcp.installUpdate(this.installationCallback);
},
installationCallback: function(error) {
if (error) {
console.log('Failed to install the update with error code: ' + error.code);
console.log(error.description);
} else {
console.log('Update installed!');
}
}
};
app.initialize();</pre>
注意: 即使你在 installUpdate
回調(diào)里處理了俱笛,相關(guān)的更新事件還是會(huì)觸發(fā)并廣播的
運(yùn)行時(shí)改變插件設(shè)置
正常情況下捆姜,所有的插件配置都在 config.xml
. 但是你可以用js動(dòng)態(tài)改變.
通過(guò)下面的代碼實(shí)現(xiàn):
<pre style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 16px; position: relative; font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace; white-space: pre-wrap; overflow-wrap: normal; overflow: auto; font-size: 13.6px; line-height: 1.45; color: rgb(0, 0, 0); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial; word-break: normal; background-color: rgb(247, 247, 247);">chcp.configure(options, callback);
function callback(error) {
// do some work
}</pre>
支持的有:
config-file
- application config(chcp.json) 的url. 如果設(shè)置了 - 這個(gè)url將會(huì)被用于檢查更新,而不是config.xml
中的值.auto-download
- 設(shè)為false
你可以禁止插件自動(dòng)檢測(cè)web內(nèi)容更新并下載.auto-install
- 設(shè)為false
你可以禁止插件自動(dòng)安裝web更新.
這些需要在 deviceready
事件中設(shè)置. 你應(yīng)該在每個(gè)頁(yè)面加載的時(shí)候處理,
假如你一開就打算手動(dòng)更新和下載安裝 - 你應(yīng)該在config.xml中設(shè)置
<pre style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 16px; position: relative; font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace; white-space: pre-wrap; overflow-wrap: normal; overflow: auto; font-size: 13.6px; line-height: 1.45; color: rgb(0, 0, 0); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial; word-break: normal; background-color: rgb(247, 247, 247);"><chcp>
<auto-download enabled="false" />
<auto-install enabled="false" />
</chcp></pre>
而不是js端動(dòng)態(tài)設(shè)置.
比如, 我們?cè)赾onfig.xml禁用了 auto-download
and auto-install
. 然后某個(gè)時(shí)間點(diǎn) config-file
改變了, 但是我們不想從原有的url檢測(cè)和下載web更新. 此時(shí), 我們應(yīng)該這樣:
發(fā)布新版本的web內(nèi)容, 它們可以用于最初的
config-file
url.-
在新的版本
index.js
文件中迎膜,內(nèi)容像這樣:<pre style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 16px; position: relative; font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace; white-space: pre-wrap; overflow-wrap: normal; overflow: auto; font-size: 13.6px; line-height: 1.45; color: rgb(0, 0, 0); word-break: normal; background-color: rgb(247, 247, 247);">var app = {
// Application Constructor
initialize: function() {
this.bindEvents();
},// Bind any events that are required.
// Usually you should subscribe on 'deviceready' event to know, when you can start calling cordova modules
bindEvents: function() {
document.addEventListener('deviceready', this.onDeviceReady, false);
},// deviceready Event Handler
onDeviceReady: function() {
// change plugin options
app.configurePlugin();
},configurePlugin: function() {
var options = {
'config-file': 'https://mynewdomain.com/some/path/mobile/chcp.json'
};chcp.configure(options, configureCallback);
},
configureCallback: function(error) {
if (error) {
console.log('Error during the configuration process');
console.log(error.description);
} else {
console.log('Plugin configured successfully');
app.checkForUpdate();
}
},checkForUpdate: function() {
chcp.fetchUpdate(this.fetchUpdateCallback);
},fetchUpdateCallback: function(error, data) {
if (error) {
console.log('Failed to load the update with error code: ' + error.code);
console.log(error.description);
return;
}
console.log('Update is loaded, running the installation');chcp.installUpdate(this.installationCallback);
},
installationCallback: function(error) {
if (error) {
console.log('Failed to install the update with error code: ' + error.code);
console.log(error.description);
} else {
console.log('Update installed!');
}
}
};app.initialize();</pre>
引導(dǎo)用戶去應(yīng)用商店更新外殼app
從 Application config app配置 小節(jié)我們知道泥技,可以給web更新設(shè)置最小支持的外殼app版本 (min_native_interface
). 如果插件檢查發(fā)現(xiàn)用戶安裝的外殼app版本比服務(wù)端新的web內(nèi)容要求的版本要低 - 就會(huì)觸發(fā)錯(cuò)誤事件,錯(cuò)誤碼chcp.error.APPLICATION_BUILD_VERSION_TOO_LOW
. 通過(guò)這個(gè)錯(cuò)誤碼我們可以引導(dǎo)用戶去應(yīng)用商店更新外殼app (Google Play /App Store).
這里你想怎么做就怎么做. 常用方法是顯示一個(gè)對(duì)話框磕仅,問(wèn)用戶是否需要轉(zhuǎn)到應(yīng)用商店. 插件也提供了這個(gè).
你需要做的是:
在 application config(chcp.json) 中設(shè)置t
android_identifier
和ios_identifier
.js端監(jiān)聽相應(yīng)事件零抬,并在出現(xiàn)錯(cuò)誤的時(shí)候調(diào)用
chcp.requestApplicationUpdate
方法.
舉個(gè)例子. 簡(jiǎn)單起見我們監(jiān)聽 chcp_updateLoadFailed
事件.
<pre style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 16px; position: relative; font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace; white-space: pre-wrap; overflow-wrap: normal; overflow: auto; font-size: 13.6px; line-height: 1.45; color: rgb(0, 0, 0); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial; word-break: normal; background-color: rgb(247, 247, 247);">var app = {
// Application Constructor
initialize: function() {
this.bindEvents();
},
// Bind any events that are required.
// Usually you should subscribe on 'deviceready' event to know, when you can start calling cordova modules
bindEvents: function() {
document.addEventListener('deviceready', this.onDeviceReady, false);
document.addEventListener('chcp_updateLoadFailed', this.onUpdateLoadError, false);
},
// deviceready Event Handler
onDeviceReady: function() {
},
onUpdateLoadError: function(eventData) {
var error = eventData.detail.error;
if (error && error.code == chcp.error.APPLICATION_BUILD_VERSION_TOO_LOW) {
console.log('Native side update required');
var dialogMessage = 'New version of the application is available on the store. Please, update.';
chcp.requestApplicationUpdate(dialogMessage, this.userWentToStoreCallback, this.userDeclinedRedirectCallback);
}
},
userWentToStoreCallback: function() {
// user went to the store from the dialog
},
userDeclinedRedirectCallback: function() {
// User didn't want to leave the app.
// Maybe he will update later.
}
};
app.initialize();</pre>
錯(cuò)誤碼
下載安裝web更新的過(guò)程中可能會(huì)發(fā)生一些錯(cuò)誤. 你可以從回調(diào)或者事件中匹配錯(cuò)誤碼( chcp.error
對(duì)象中有各種錯(cuò)誤碼).
v1.2.0版本之前 你需要用特定的錯(cuò)誤碼數(shù)字值. 此時(shí)開始, 請(qǐng)使用靜態(tài)常量名镊讼,這樣可以使代碼可讀宽涌,也可以減少對(duì)錯(cuò)誤碼具體數(shù)字的依賴. 比如, 不應(yīng)該用 if (error.code == -2)
而用 if (error.code == chcp.error.APPLICATION_BUILD_VERSION_TOO_LOW)
.
錯(cuò)誤列表:
NOTHING_TO_INSTALL
- 請(qǐng)求插件安裝更新平夜,卻沒有更新需要安裝. 值為1
.NOTHING_TO_UPDATE
- 沒有可用web更新需要下載.值為2
.FAILED_TO_DOWNLOAD_APPLICATION_CONFIG
- 下載新的application config 文件(chcp.json)失敗. 要么文件不存在或者網(wǎng)絡(luò)問(wèn)題.值為-1
.APPLICATION_BUILD_VERSION_TOO_LOW
- 外殼app的build版本號(hào)太低. 新的web內(nèi)容需要新的外殼app. 用戶需要更新外殼app.值為-2
.FAILED_TO_DOWNLOAD_CONTENT_MANIFEST
- 下載內(nèi)容清單文件(chcp.manifest)失敗. 文件chcp.manifest
必須位于content_url
對(duì)應(yīng)目錄下, 和chcp.json一起.值為-3
.FAILED_TO_DOWNLOAD_UPDATE_FILES
- 下載web內(nèi)容失敗. 清單chcp.manifest
中列出文件的必須都要位于content_url
對(duì)應(yīng)目錄下. 還有, 檢查各個(gè)文件的MD5是否正確. 值為-4
.FAILED_TO_MOVE_LOADED_FILES_TO_INSTALLATION_FOLDER
- 移動(dòng)已下載的文件到安裝目錄時(shí)失敗. 可能存儲(chǔ)空間不足.值為-5
.UPDATE_IS_INVALID
- web內(nèi)容已損壞. 安裝之前,插件會(huì)檢查已下載文件的MD5和chcp.manifest
中的比較看是否一致. 如果不一致或者文件缺失 - 會(huì)發(fā)生此錯(cuò)誤. 值為-6
.FAILED_TO_COPY_FILES_FROM_PREVIOUS_RELEASE
- 從上一版本拷貝www下文件到新版本www目錄出錯(cuò).可能存儲(chǔ)空間不足.值為-7
.FAILED_TO_COPY_NEW_CONTENT_FILES
- 拷貝新文件到內(nèi)容目錄下失敗.可能存儲(chǔ)空間不足.值為-8
.LOCAL_VERSION_OF_APPLICATION_CONFIG_NOT_FOUND
- 加載本地chcp.json失敗. 可能是用戶手動(dòng)刪除了外部存儲(chǔ)的web內(nèi)容相關(guān)文件. 如果發(fā)生卸亮,會(huì)回滾至上移release版本的web內(nèi)容.值為-9
.LOCAL_VERSION_OF_MANIFEST_NOT_FOUND
-加載本地chcp.manifest失敗.可能是用戶手動(dòng)刪除了外部存儲(chǔ)的web內(nèi)容相關(guān)文件. 如果發(fā)生忽妒,會(huì)回滾至上移release版本的web內(nèi)容. 值為-10
.LOADED_VERSION_OF_APPLICATION_CONFIG_NOT_FOUND
-加載本地已下載的新版本的chcp.json失敗.可能是用戶手動(dòng)刪除了外部存儲(chǔ)的web內(nèi)容相關(guān)文件.如果發(fā)生 - app下次啟動(dòng)時(shí)會(huì)恢復(fù). 值為-11
.LOADED_VERSION_OF_MANIFEST_NOT_FOUND
-加載本地已下載的新版本的chcp.manifest失敗.可能是用戶手動(dòng)刪除了外部存儲(chǔ)的web內(nèi)容相關(guān)文件.如果發(fā)生 - app下次啟動(dòng)時(shí)會(huì)恢復(fù).值為-12
.FAILED_TO_INSTALL_ASSETS_ON_EXTERNAL_STORAGE
- 拷貝app內(nèi)置web內(nèi)容到外部存儲(chǔ)時(shí)失敗.可能存儲(chǔ)空間不足. app初次啟動(dòng)時(shí)會(huì)執(zhí)行此操作. 如果失敗,插件就不再有用了. 值為-13
.CANT_INSTALL_WHILE_DOWNLOAD_IN_PROGRESS
- 調(diào)用chcp.installUpdate
而 插件正在下載更新時(shí)觸發(fā). 你必須等待下載完畢. 值為-14
.CANT_DOWNLOAD_UPDATE_WHILE_INSTALLATION_IN_PROGRESS
- 調(diào)用chcp.fetchUpdate
而安裝過(guò)程在再執(zhí)行. 你必須等待安裝完畢. 值為-15
.INSTALLATION_ALREADY_IN_PROGRESS
- 調(diào)用chcp.installUpdate
,而安裝過(guò)程在再執(zhí)行.值為-16
.DOWNLOAD_ALREADY_IN_PROGRESS
- 調(diào)用chcp.fetchUpdate
,而 插件正在下載更新時(shí)觸發(fā). 值為-17
.ASSETS_FOLDER_IN_NOT_YET_INSTALLED
- 調(diào)用chcp
方法, 而插件正在拷貝app內(nèi)置web內(nèi)容到外部存儲(chǔ)時(shí)觸發(fā). 只可能在app初次啟動(dòng)時(shí)發(fā)生. 最后這個(gè)錯(cuò)誤會(huì)被移除.值為-18
.
關(guān)于熱更新的流程解析
好多同學(xué)都測(cè)試不成功兼贸,大家不要想太復(fù)雜了段直,我再簡(jiǎn)要概括一下:
- chcp.json文件中的content_url為服務(wù)器項(xiàng)目的地址加端口號(hào)
- config.xml為服務(wù)器項(xiàng)目地址加端口號(hào)再加上/chcp.json
- 每次修改完文件后,必須將【修改的文件】和【chcp.manifest文件】一并復(fù)制到服務(wù)器項(xiàng)目中進(jìn)行覆蓋溶诞。
- 將服務(wù)器中的chcp.json文件中的【"release": "2016.08.04-18.04.06"】時(shí)間改為當(dāng)前時(shí)間鸯檬。
3 和 4是最重要的,不然熱更新就不起作用螺垢。
最后你們不要在糾結(jié)cordova-hcp server喧务,這個(gè)東西就是在開發(fā)的時(shí)候啟動(dòng)用來(lái)監(jiān)聽文件的修改,如果有文件修改枉圃,就對(duì)應(yīng)在chcp.manifest中修改該文件的hash值功茴。
還沒完,為了更清楚的了解熱更新是怎么回事孽亲,這里我畫了一張圖坎穿。
[熱更新的流程解析]
[圖片上傳中...(image-5f8fb-1557555367321-2)]
- app啟動(dòng)
- 從服務(wù)器請(qǐng)求chcp.json文件(會(huì)覆蓋本地chcp.json文件)。
- 服務(wù)器返回chcp.json文件與app里的chcp.json文件做對(duì)比返劲,判斷兩個(gè)文件中的release時(shí)間玲昧。
- 如果服務(wù)器chcp.json文件的release時(shí)間大于app里chcp.json的release時(shí)間(說(shuō)明新的資源)
- 如果有新的資源,再次發(fā)送一個(gè)請(qǐng)求篮绿,請(qǐng)求服務(wù)器的chcp.manifest文件(會(huì)覆蓋本地chcp.json文件)孵延。
- 服務(wù)器返回chcp.manifest文件與app里的chcp.manifest文件內(nèi)容做對(duì)比。
- 如果有不一樣的hash值搔耕。
- 對(duì)服務(wù)器請(qǐng)求新的資源隙袁。
- 請(qǐng)求成功的資源將覆蓋本地資源。
案例
這里通過(guò)對(duì)app進(jìn)行抓包弃榨,來(lái)分析熱更新是怎樣進(jìn)行應(yīng)用內(nèi)更新的菩收。注意看1~8,我是沒有對(duì)服務(wù)器資源進(jìn)行更新的鲸睛。直到第9個(gè)請(qǐng)求的時(shí)候:9娜饵,10,11連續(xù)發(fā)送了3個(gè)請(qǐng)求官辈。
[熱更新的抓包圖]
[圖片上傳中...(image-f38240-1557555367321-1)]
- 第9個(gè)請(qǐng)求將服務(wù)器的chcp.json文件請(qǐng)求回來(lái)后判斷時(shí)間是大于app的chcp.json時(shí)間的
- 然后發(fā)送了第10個(gè)請(qǐng)求箱舞,chcp.manifest遍坟,與本地chcp.manifest文件做對(duì)比
- 其中我只改了一個(gè)login.html,所以這里對(duì)login.html重新加載覆蓋晴股。
一直有人問(wèn)我愿伴,用不了,不會(huì)用之類的。我在這說(shuō)一下
[圖片上傳中...(image-83354d-1557555367321-0)]
用 cordova-hcp server 命令啟動(dòng) hcp 服務(wù)器的時(shí)候,會(huì)看到如上圖的local server 和public server前方,這兩個(gè)地址是不能自己定義的
類似“https://f5f6894c.ngrok.io” 這個(gè)地址貌似并沒有用碟联,也許只是國(guó)內(nèi)沒法用吧
所以,我建議不要用 cordova-hcp server,你需要自己部署一個(gè)服務(wù)器,托管 www 下的 web 內(nèi)容
Local Development Add-on 這個(gè)擴(kuò)展也可以不要,記得自己生成新的apk/ipa之前要改config.xml的version(android-versionCode/ios-CFBundleVersion)就行了
其實(shí) cordova-hcp server 啟動(dòng)的那個(gè)服務(wù)器幻妓,就是多了2個(gè)功能:
1、檢測(cè)到 www 變更后劫拢,自動(dòng)生成清單文件 chcp.manifest
2肉津、自動(dòng)實(shí)時(shí)推送變更到app端
用了你自己的服務(wù)器之后,這2個(gè)功能都沒了尚镰。所以
1阀圾、每次更改 www 下的 web 內(nèi)容之后,一定要手動(dòng)用 cordova-hcp build(在corodva項(xiàng)目根目錄下執(zhí)行)狗唉, 生成清單文件 chcp.manifest
2初烘、app 只能在每次啟動(dòng)的時(shí)候,才能檢查有無(wú)內(nèi)容更新分俯。有更新就會(huì)在后臺(tái)下載肾筐,等到下次啟動(dòng) app 才應(yīng)用更新。(也就是要重啟app 2次才能看到效果)
chcp.json 這個(gè)文件的內(nèi)容也要改下缸剪,把 update 改為 "start"吗铐,比如
[javascript] view plaincopy
<embed id="ZeroClipboardMovie_1" src="https://csdnimg.cn/public/highlighter/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" width="16" height="16" name="ZeroClipboardMovie_1" align="middle" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=1&width=16&height=16" wmode="transparent" style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; overflow-wrap: break-word;">
<embed id="ZeroClipboardMovie_3" src="https://csdnimg.cn/public/highlighter/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" width="16" height="16" name="ZeroClipboardMovie_3" align="middle" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=3&width=16&height=16" wmode="transparent" style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; overflow-wrap: break-word;">
- {
- "update": "start",
- "content_url": "http://10.0.0.100/HCP/",
- "release": "2016.04.28-10.14.32"
- }
{ "update": "start", "content_url": "http://10.0.0.100/HCP/", "release": "2016.04.28-10.14.32"}
chcp.json 的功能,不懂的看上面翻譯
可以在 cordova 項(xiàng)目根目錄下放一個(gè) cordova-hcp.json杏节,這是個(gè)模板文件
這樣每次執(zhí)行 cordova-hcp build, 就會(huì)利用這個(gè)模板生成新的 chcp.json唬渗,而不用手動(dòng)更改 www/chcp.json了。
cordova-hcp.json內(nèi)容如下:
[javascript] view plaincopy
<embed id="ZeroClipboardMovie_2" src="https://csdnimg.cn/public/highlighter/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" width="16" height="16" name="ZeroClipboardMovie_2" align="middle" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=2&width=16&height=16" wmode="transparent" style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; overflow-wrap: break-word;">
<embed id="ZeroClipboardMovie_4" src="https://csdnimg.cn/public/highlighter/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" width="16" height="16" name="ZeroClipboardMovie_4" align="middle" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=4&width=16&height=16" wmode="transparent" style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; overflow-wrap: break-word;">
- {
- "update": "start",
- "content_url": "http://10.0.0.100/HCP/"
- }
{ "update": "start", "content_url": "http://10.0.0.100/HCP/"}