onLaunch / onShow / onHide 三個(gè)回調(diào)是App實(shí)例的生命周期函數(shù)
“小程序”指的是產(chǎn)品層面的程序,而“程序”指的是代碼層面的程序?qū)嵗瑸榱吮苊庹`解,下文采用App來代替代碼層面的“程序”概念。
宿主環(huán)境提供了 App() 構(gòu)造器用來注冊(cè)一個(gè)程序App,需要留意的是App() 構(gòu)造器必須寫在項(xiàng)目根目錄的app.js里,App實(shí)例是單例對(duì)象,在其他JS腳本中可以使用宿主環(huán)境提供的 getApp() 來獲取程序?qū)嵗?/p>
代碼獲取App實(shí)例
// other.js var appInstance = getApp()
App() 的調(diào)用方式如代碼清單3-4所示,App構(gòu)造器接受一個(gè)Object參數(shù),參數(shù)說明如表3-1所示,其中onLaunch / onShow / onHide 三個(gè)回調(diào)是App實(shí)例的生命周期函數(shù),我們會(huì)在后文展開;onError我們暫時(shí)不在本章展開,我們會(huì)在第8章里詳細(xì)討論;App的其他參數(shù)我們也放在后文進(jìn)行展開。
代碼 App構(gòu)造器
App({ onLaunch: function(options) {}, onShow: function(options) {}, onHide: function() {}, onError: function(msg) {}, globalData: 'I am global data' }) |
App構(gòu)造器參數(shù)
參數(shù)屬性 | 類型 | 描述 |
---|---|---|
onLaunch | Function | 當(dāng)小程序初始化完成時(shí),會(huì)觸發(fā) onLaunch(全局只觸發(fā)一次) |
onShow | Function | 當(dāng)小程序啟動(dòng),或從后臺(tái)進(jìn)入前臺(tái)顯示,會(huì)觸發(fā) onShow |
onHide | Function | 當(dāng)小程序從前臺(tái)進(jìn)入后臺(tái),會(huì)觸發(fā) onHide |
onError | Function | 當(dāng)小程序發(fā)生腳本錯(cuò)誤,或者 API 調(diào)用失敗時(shí),會(huì)觸發(fā) onError 并帶上錯(cuò)誤信息 |
其他字段 | 任意 | 可以添加任意的函數(shù)或數(shù)據(jù)到 Object 參數(shù)中,在App實(shí)例回調(diào)用 this 可以訪問 |
初次進(jìn)入小程序的時(shí)候,微信客戶端初始化好宿主環(huán)境,同時(shí)從網(wǎng)絡(luò)下載或者從本地緩存中拿到小程序的代碼包,把它注入到宿主環(huán)境,初始化完畢后,微信客戶端就會(huì)給App實(shí)例派發(fā)onLaunch事件,App構(gòu)造器參數(shù)所定義的onLaunch方法會(huì)被調(diào)用。
進(jìn)入小程序之后,用戶可以點(diǎn)擊右上角的關(guān)閉,或者按手機(jī)設(shè)備的Home鍵離開小程序,此時(shí)小程序并沒有被直接銷毀,我們把這種情況稱為“小程序進(jìn)入后臺(tái)狀態(tài)”,App構(gòu)造器參數(shù)所定義的onHide方法會(huì)被調(diào)用。
當(dāng)再次回到微信或者再次打開小程序時(shí),微信客戶端會(huì)把“后臺(tái)”的小程序喚醒,我們把這種情況稱為“小程序進(jìn)入前臺(tái)狀態(tài)”,App構(gòu)造器參數(shù)所定義的onShow方法會(huì)被調(diào)用。
我們可以看到,App的生命周期是由微信客戶端根據(jù)用戶操作主動(dòng)觸發(fā)的。為了避免程序上的混亂,我們不應(yīng)該從其他代碼里主動(dòng)調(diào)用App實(shí)例的生命周期函數(shù)。
在微信客戶端中打開小程序有很多途徑:從群聊會(huì)話里打開,從小程序列表中打開,通過微信掃一掃二維碼打開,從另外一個(gè)小程序打開當(dāng)前小程序等,針對(duì)不同途徑的打開方式,小程序有時(shí)需要做不同的業(yè)務(wù)處理,所以微信客戶端會(huì)把打開方式帶給onLaunch和onShow的調(diào)用參數(shù)options,示例代碼以及詳細(xì)參數(shù)如代碼清單3-5和表3-2所示。需要留意小程序的宿主環(huán)境在迭代更新過程會(huì)增加不少打開場(chǎng)景,因此要獲取最新的場(chǎng)景值說明請(qǐng)查看官方文檔:https://mp.weixin.qq.com/debug/wxadoc/dev/framework/app-service/app.html。
代碼清單3-5 onLaunch和onShow帶參數(shù)
App({ onLaunch: function(options) { console.log(options) }, onShow: function(options) { console.log(options) } }) |
onLaunch,onShow參數(shù)
字段 | 類型 | 描述 |
---|---|---|
path | String | 打開小程序的頁面路徑 |
query | Object | 打開小程序的頁面參數(shù)query |
scene | Number | 打開小程序的場(chǎng)景值,詳細(xì)場(chǎng)景值請(qǐng)參考小程序官方文檔 |
shareTicket | String | shareTicket,詳見小程序官方文檔 |
referrerInfo | Object | 當(dāng)場(chǎng)景為由從另一個(gè)小程序或公眾號(hào)或App打開時(shí),返回此字段 |
referrerInfo.appId | String | 來源小程序或公眾號(hào)或App的 appId,詳見下方說明 |
referrerInfo.extraData | Object | 來源小程序傳過來的數(shù)據(jù),scene=1037或1038時(shí)支持 |
以下場(chǎng)景支持返回 referrerInfo.appId
場(chǎng)景值 | 場(chǎng)景 | appId信息含義 |
---|---|---|
1020 | 公眾號(hào) profile | 頁相關(guān)小程序列表 返回來源公眾號(hào) appId |
1035 | 公眾號(hào)自定義菜單 | 返回來源公眾號(hào) appId |
1036 | App 分享消息卡片 | 返回來源應(yīng)用 appId |
1037 | 小程序打開小程序 | 返回來源小程序 appId |
1038 | 從另一個(gè)小程序返回 | 返回來源小程序 appId |
1043 | 公眾號(hào)模板消息 | 返回來源公眾號(hào) appId |
之前說到小程序的JS腳本是運(yùn)行在JsCore的線程里,小程序的每個(gè)頁面各自有一個(gè)WebView線程進(jìn)行渲染,所以小程序切換頁面時(shí),小程序邏輯層的JS腳本運(yùn)行上下文依舊在同一個(gè)JsCore線程中。
在上文中說道App實(shí)例是單例的,因此不同頁面直接可以通過App實(shí)例下的屬性來共享數(shù)據(jù)。App構(gòu)造器可以傳遞其他參數(shù)作為全局屬性以達(dá)到全局共享數(shù)據(jù)的目的。
代碼小程序全局共享數(shù)據(jù)
// app.js App({ globalData: 'I am global data' // 全局共享數(shù)據(jù) }) // 其他頁面腳本other.js var appInstance = getApp() console.log(appInstance.globalData) // 輸出: I am global data |
與此同時(shí),我們要特別留意一點(diǎn),所有頁面的腳本邏輯都跑在同一個(gè)JsCore線程,頁面使用setTimeout或者setInterval的定時(shí)器,然后跳轉(zhuǎn)到其他頁面時(shí),這些定時(shí)器并沒有被清除,需要開發(fā)者自己在頁面離開的時(shí)候進(jìn)行清理。
小程序啟動(dòng)會(huì)有兩種情況,一種是「冷啟動(dòng)」,一種是「熱啟動(dòng)」。 假如用戶已經(jīng)打開過某小程序,然后在一定時(shí)間內(nèi)再次打開該小程序,此時(shí)無需重新啟動(dòng),只需將后臺(tái)態(tài)的小程序切換到前臺(tái),這個(gè)過程就是熱啟動(dòng);冷啟動(dòng)指的是用戶首次打開或小程序被微信主動(dòng)銷毀后再次打開的情況,此時(shí)小程序需要重新加載啟動(dòng)。
更新機(jī)制:小程序冷啟動(dòng)時(shí)如果發(fā)現(xiàn)有新版本,將會(huì)異步下載新版本的代碼包,并同時(shí)用客戶端本地的包進(jìn)行啟動(dòng),即新版本的小程序需要等下一次冷啟動(dòng)才會(huì)應(yīng)用上。