微信小程序 運(yùn)行機(jī)制

2022-05-11 15:26 更新

小程序運(yùn)行機(jī)制

前臺(tái)/后臺(tái)狀態(tài)

小程序啟動(dòng)后,界面被展示給用戶(hù),此時(shí)小程序處于前臺(tái)狀態(tài)。

當(dāng)用戶(hù)點(diǎn)擊右上角膠囊按鈕關(guān)閉小程序,或者按了設(shè)備 Home 鍵離開(kāi)微信時(shí),小程序并沒(méi)有完全終止運(yùn)行,而是進(jìn)入了后臺(tái)狀態(tài),小程序還可以運(yùn)行一小段時(shí)間。

當(dāng)用戶(hù)再次進(jìn)入微信或再次打開(kāi)小程序,小程序又會(huì)從后臺(tái)進(jìn)入前臺(tái)。但如果用戶(hù)很久沒(méi)有再進(jìn)入小程序,或者系統(tǒng)資源緊張,小程序可能被銷(xiāo)毀,即完全終止運(yùn)行。

小程序啟動(dòng)

這樣,小程序啟動(dòng)可以分為兩種情況,一種是冷啟動(dòng),一種是熱啟動(dòng)。

  • 冷啟動(dòng):如果用戶(hù)首次打開(kāi),或小程序銷(xiāo)毀后被用戶(hù)再次打開(kāi),此時(shí)小程序需要重新加載啟動(dòng),即冷啟動(dòng)。
  • 熱啟動(dòng):如果用戶(hù)已經(jīng)打開(kāi)過(guò)某小程序,然后在一定時(shí)間內(nèi)再次打開(kāi)該小程序,此時(shí)小程序并未被銷(xiāo)毀,只是從后臺(tái)狀態(tài)進(jìn)入前臺(tái)狀態(tài),這個(gè)過(guò)程就是熱啟動(dòng)。

小程序銷(xiāo)毀時(shí)機(jī)

通常,只有當(dāng)小程序進(jìn)入后臺(tái)一定時(shí)間,或者系統(tǒng)資源占用過(guò)高,才會(huì)被銷(xiāo)毀。具體而言包括以下幾種情形:

  • 當(dāng)小程序進(jìn)入后臺(tái),可以維持一小段時(shí)間的運(yùn)行狀態(tài),如果這段時(shí)間內(nèi)都未進(jìn)入前臺(tái),小程序會(huì)被銷(xiāo)毀。
  • 當(dāng)小程序占用系統(tǒng)資源過(guò)高,可能會(huì)被系統(tǒng)銷(xiāo)毀或被微信客戶(hù)端主動(dòng)回收。在 iOS 上,當(dāng)微信客戶(hù)端在一定時(shí)間間隔內(nèi)連續(xù)收到系統(tǒng)內(nèi)存告警時(shí),會(huì)根據(jù)一定的策略,主動(dòng)銷(xiāo)毀小程序,并提示用戶(hù) 「運(yùn)行內(nèi)存不足,請(qǐng)重新打開(kāi)該小程序」。具體策略會(huì)持續(xù)進(jìn)行調(diào)整優(yōu)化。建議小程序在必要時(shí)使用 wx.onMemoryWarning 監(jiān)聽(tīng)內(nèi)存告警事件,進(jìn)行必要的內(nèi)存清理。
基礎(chǔ)庫(kù) 1.1.0 及以上,1.4.0 以下版本: 當(dāng)用戶(hù)從掃一掃、轉(zhuǎn)發(fā)等入口(場(chǎng)景值為1007, 1008, 1011, 1025)進(jìn)入小程序,且沒(méi)有置頂小程序的情況下退出,小程序會(huì)被銷(xiāo)毀。

啟動(dòng)場(chǎng)景分類(lèi)

用戶(hù)打開(kāi)小程序時(shí),場(chǎng)景可分為以下 A、B 兩類(lèi):

A. 保留上次的瀏覽狀態(tài)。場(chǎng)景值有以下幾項(xiàng):

場(chǎng)景值ID 說(shuō)明
1001 發(fā)現(xiàn)欄小程序主入口,「最近使用」列表(基礎(chǔ)庫(kù)2.2.4版本起包含「我的小程序」列表)
1003 星標(biāo)小程序列表
1023 系統(tǒng)桌面小圖標(biāo)打開(kāi)小程序
1038 從其他小程序返回小程序
1056 聊天頂部音樂(lè)播放器右上角菜單,打開(kāi)小程序
1080 客服會(huì)話(huà)菜單小程序入口,打開(kāi)小程序
1083 公眾號(hào)會(huì)話(huà)菜單小程序入口 ,打開(kāi)小程序(只有騰訊客服小程序有)
1089 聊天主界面下拉,打開(kāi)小程序/微信聊天主界面下拉,「最近使用」欄(基礎(chǔ)庫(kù)2.2.4版本起包含「我的小程序」欄)
1090 長(zhǎng)按小程序右上角菜單,打開(kāi)小程序
1103 發(fā)現(xiàn)-小程序主入口我的小程序,打開(kāi)小程序
1104 聊天主界面下拉,從我的小程序,打開(kāi)小程序
1113 安卓手機(jī)負(fù)一屏,打開(kāi)小程序
1114 安卓手機(jī)側(cè)邊欄,打開(kāi)小程序
1117 后臺(tái)運(yùn)行小程序的管理頁(yè)中,打開(kāi)小程序
  • 若進(jìn)入的場(chǎng)景中帶有 path,則每次打開(kāi)小程序時(shí)都進(jìn)入對(duì)應(yīng)的 path 頁(yè)面
  • 若進(jìn)入的場(chǎng)景中不帶 path:若小程序是熱啟動(dòng),則保留原來(lái)狀態(tài)若小程序是冷啟動(dòng),則遵循下一節(jié)的重啟策略,可能是首頁(yè)或上次退出的頁(yè)面

B. relaunch 到指定頁(yè)或首頁(yè)

包括除 A 類(lèi)外的其他場(chǎng)景

  • 若進(jìn)入的場(chǎng)景中帶有 path,則每次點(diǎn)擊時(shí)都進(jìn)入對(duì)應(yīng)的 path 頁(yè)面
  • 若進(jìn)入的場(chǎng)景中不帶 path,則每次進(jìn)入都打開(kāi)首頁(yè)

A 類(lèi)場(chǎng)景的重新啟動(dòng)策略

基礎(chǔ)庫(kù) 2.8.0 開(kāi)始支持,低版本需做兼容處理

小程序被銷(xiāo)毀后,下次冷啟動(dòng)如果屬于 B 類(lèi)場(chǎng)景,將會(huì)進(jìn)入特定的頁(yè)面。

下次冷啟動(dòng)如果屬于 A 類(lèi)場(chǎng)景,默認(rèn)情況下將會(huì)進(jìn)入小程序的首頁(yè)。在頁(yè)面對(duì)應(yīng)的 json 文件中(也可以全局配置在 app.json 的 window 段中),指定 restartStrategy 配置項(xiàng)可以改變這個(gè)默認(rèn)的行為,使得從某個(gè)頁(yè)面退出后,下次 A 類(lèi)場(chǎng)景的冷啟動(dòng)可以回到這個(gè)頁(yè)面。

代碼示例:

{
  "restartStrategy": "homePage"
}

restartStrategy 可選值:

可選值 含義
homePage (默認(rèn)值)如果從這個(gè)頁(yè)面退出小程序,下次將從首頁(yè)冷啟動(dòng)
homePageAndLatestPage 如果從這個(gè)頁(yè)面退出小程序,下次冷啟動(dòng)后立刻加載這個(gè)頁(yè)面,頁(yè)面的參數(shù)保持不變(不可用于 tab 頁(yè))

注意:即使不配置為 homePage ,小程序如果退出過(guò)久(當(dāng)前默認(rèn)一天時(shí)間,可以使用退出狀態(tài)來(lái)調(diào)整),下次冷啟動(dòng)時(shí)也將不再遵循 restartStrategy 的配置,而是直接從首頁(yè)冷啟動(dòng)。

無(wú)論如何,頁(yè)面中的狀態(tài)并不會(huì)被保留,如輸入框中的文本內(nèi)容、 checkbox 的勾選狀態(tài)等都不會(huì)還原。如果需要還原或部分還原,需要利用退出狀態(tài)。

退出狀態(tài)

每當(dāng)小程序可能被銷(xiāo)毀之前,頁(yè)面回調(diào)函數(shù) onSaveExitState 會(huì)被調(diào)用。如果想保留頁(yè)面中的狀態(tài),可以在這個(gè)回調(diào)函數(shù)中“保存”一些數(shù)據(jù),下次啟動(dòng)時(shí)可以通過(guò) exitState 獲得這些已保存數(shù)據(jù)。

代碼示例:

{
  "restartStrategy": "homePageAndLatestPage"
}
Page({
  onLoad: function() {
    var prevExitState = this.exitState // 嘗試獲得上一次退出前 onSaveExitState 保存的數(shù)據(jù)
    if (prevExitState !== undefined) { // 如果是根據(jù) restartStrategy 配置進(jìn)行的冷啟動(dòng),就可以獲取到
      prevExitState.myDataField === 'myData' 
    }
  },
  onSaveExitState: function() {
    var exitState = { myDataField: 'myData' } // 需要保存的數(shù)據(jù)
    return {
      data: exitState,
      expireTimeStamp: Date.now() + 24 * 60 * 60 * 1000 // 超時(shí)時(shí)刻
    }
  }
})

onSaveExitState 返回值可以包含兩項(xiàng):

字段名 類(lèi)型 含義
data Any 需要保存的數(shù)據(jù)(只能是 JSON 兼容的數(shù)據(jù))
expireTimeStamp Number 超時(shí)時(shí)刻,在這個(gè)時(shí)刻后,保存的數(shù)據(jù)保證一定被丟棄,默認(rèn)為 (當(dāng)前時(shí)刻 + 1 天)


注意事項(xiàng):

  • 如果超過(guò) expireTimeStamp ,保存的數(shù)據(jù)將被丟棄,且冷啟動(dòng)時(shí)不遵循 restartStrategy 的配置,而是直接從首頁(yè)冷啟動(dòng)。
  • expireTimeStamp 有可能被自動(dòng)提前,如微信客戶(hù)端需要清理數(shù)據(jù)的時(shí)候。
  • 在小程序存活期間, onSaveExitState 可能會(huì)被多次調(diào)用,此時(shí)以最后一次的調(diào)用結(jié)果作為最終結(jié)果。
  • 在某些特殊情況下(如微信客戶(hù)端直接被系統(tǒng)殺死),這個(gè)方法將不會(huì)被調(diào)用,下次冷啟動(dòng)也不遵循 restartStrategy 的配置,而是直接從首頁(yè)冷啟動(dòng)。


以上內(nèi)容是否對(duì)您有幫助:
在線(xiàn)筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)