發布日期:2020 年 12 月 2 日
自從推出Trusted Web Activity 後,Chrome 團隊已簡化 Bubblewrap 的使用方式。我們新增了其他功能 (例如 Google Play 帳款服務整合),並讓這項服務能夠在更多平台上運作,例如 ChromeOS。
Bubblewrap 和 Trusted Web Activity 功能
Bubblewrap 可協助您建立應用程式,在信任的網頁活動中啟動 PWA,無須瞭解特定平台的工具。
簡化設定流程
先前,使用 Bubblewrap 需要手動設定 Java Development Kit 和 Android SDK,這兩者都容易發生錯誤。這項工具現在會在首次執行時自動下載外部依附元件。
您仍可選擇使用現有的依附元件安裝作業 (如果您偏好這樣做),而新的 doctor
指令可協助找出問題,並建議修正設定,現在您可以透過指令列使用 updateConfig
指令更新設定。
改善精靈
使用 init
建立專案時,Bubblewrap 需要產生 Android 應用程式所需的資訊。這項工具會從 Web App 資訊清單中擷取值,並在可行時提供預設值。
您可以在建立新專案時變更這些值,但先前各欄位的含義並不明確。我們重新建構了初始化對話方塊,為每個輸入欄位提供更詳盡的說明和驗證。
顯示全螢幕和螢幕方向支援
在某些情況下,您可能希望應用程式盡可能使用螢幕的所有空間,在建構 PWA 時,您可以將 display
欄位從網頁應用程式資訊清單設為 fullscreen
,實現這項功能。
當 Bubblewrap 在 Web 應用程式資訊清單中偵測到全螢幕選項時,就會將 Android 應用程式設為以全螢幕模式 (或以 Android 專屬術語來說,就是「沉浸式模式」) 啟動。
網頁應用程式資訊清單中的 orientation
欄位會定義應用程式應以直向模式、橫向模式,還是裝置目前使用的方向啟動。Bubblewrap 現已讀取 Web App 資訊清單欄位,並在建立 Android 應用程式時將其用作預設值。
您可以自訂這兩種設定,並納入 bubblewrap init
流程中。
AppBundles 輸出內容
App Bundle 是一種應用程式發布格式,可將產生及簽署最終 APK 的作業委派給 Play。實際上,這可讓使用者在從商店下載應用程式時,取得較小的檔案。
Bubblewrap 會將應用程式封裝為應用程式軟體包,並儲存在名為 app-release-bundle.aab
的檔案中。發布應用程式至 Play 商店時,建議您採用這個格式,因為 商店自 2021 年起就要求使用這個格式。
地理位置委派
無論技術為何,使用者都希望在裝置上安裝的應用程式能夠一致運作。在信任的 Web Activity 中使用時,現在可以將 GeoLocation 權限委派給作業系統,這樣一來,使用者啟用權限後,就會看到與使用 Kotlin 或 Java 建構的應用程式相同的對話方塊,並在同一個位置找到用於管理權限的控制項。
這項功能可透過 Bubblewrap 新增,但由於它會為 Android 專案新增額外依附元件,因此您應僅在網頁應用程式使用地理位置權限時啟用這項功能。
最佳化二進位檔
在世界某些地區,儲存空間有限的裝置很常見,而這些裝置的使用者通常偏好較小的應用程式。使用信任的網路活動的應用程式會產生小型二進位檔,可消除使用者的部分疑慮。
Bubblewrap 已經過最佳化,減少所需 Android 程式庫的清單,產生的二進位檔因此縮小了 800k。實際上,這比先前版本產生的平均大小還小一半。如要充分利用較小的二進位檔,您只需使用最新版本的 Bubblewrap 更新應用程式即可。
如何更新現有應用程式
Bubblewrap 產生的應用程式由網頁應用程式和可開啟 PWA 的輕量 Android 包裝函式組成。雖然在可信任的網頁活動中開啟的 PWA 會遵循與任何網頁應用程式相同的更新週期,但原生包裝函式可以且應進行更新。
您應更新應用程式,確保應用程式使用最新版本的包裝函式,並包含最新的錯誤修正和功能。安裝最新版的 Bubblewrap 後,update
指令會將最新版的包裝函式套用至現有專案:
npm update -g @bubblewrap/cli bubblewrap update bubblewrap build
更新這些應用程式的另一個原因,是為了確保網頁資訊清單的變更會套用至應用程式。請使用新的 merge
指令:
bubblewrap merge bubblewrap update bubblewrap build
品質標準更新
Chrome 86 推出了受信任網路活動品質標準的變更,詳情請參閱「透過受信任網路活動整合 PWA 時的品質標準有所變更」一文。
簡單來說,您必須確保應用程式能夠處理下列情況,以免發生當機情形:
- 無法在應用程式啟動時驗證數位資產連結
- 無法針對離線網路資源要求傳回 HTTP 200
- 應用程式傳回 HTTP 404 或 5xx 錯誤。
除了確保應用程式通過Digital Asset Links 驗證之外,服務工作程式也可以處理其他情況:
self.addEventListener('fetch', event => { event.respondWith((async () => { try { return await fetchAndHandleError(event.request); } catch { // Failed to load from the network. User is offline or the response // has a status code that triggers the Quality Criteria. // Try loading from cache. const cachedResponse = await caches.match(event.request); if (cachedResponse) { return cachedResponse; } // Response was not found on the cache. Send the error / offline // page. OFFLINE_PAGE should be pre-cached when the service worker // is activated. return await caches.match(OFFLINE_PAGE); } })()); }); async function fetchAndHandleError(request) { const cache = await caches.open(RUNTIME_CACHE); const response = await fetch(request); // Throw an error if the response returns one of the status // that trigger the Quality Criteria. if (response.status === 404 || response.status >= 500 && response.status < 600) { throw new Error(`Server responded with status: ${response.status}`); } // Cache the response if the request is successful. cache.put(request, response.clone()); return response; }
Workbox 會採用最佳做法,並在使用服務工作者時移除常用程式碼。或者,您也可以考慮使用 Workbox 外掛程式來處理這些情況:
export class FallbackOnErrorPlugin { constructor(offlineFallbackUrl, notFoundFallbackUrl, serverErrorFallbackUrl) { this.notFoundFallbackUrl = notFoundFallbackUrl; this.offlineFallbackUrl = offlineFallbackUrl; this.serverErrorFallbackUrl = serverErrorFallbackUrl; } checkTrustedWebActivityCrash(response) { if (response.status === 404 || response.status >= 500 && response.status <= 600) { const type = response.status === 404 ? 'E_NOT_FOUND' : 'E_SERVER_ERROR'; const error = new Error(`Invalid response status (${response.status})`); error.type = type; throw error; } } // This is called whenever there's a network response, // but we want special behavior for 404 and 5**. fetchDidSucceed({response}) { // Cause a crash if this is a Trusted Web Activity crash. this.checkTrustedWebActivityCrash(response); // If it's a good response, it can be used as-is. return response; } // This callback is new in Workbox v6, and is triggered whenever // an error (including a NetworkError) is thrown when a handler runs. handlerDidError(details) { let fallbackURL; switch (details.error.details.error.type) { case 'E_NOT_FOUND': fallbackURL = this.notFoundFallbackUrl; break; case 'E_SERVER_ERROR': fallbackURL = this.serverErrorFallbackUrl; break; default: fallbackURL = this.offlineFallbackUrl; } return caches.match(fallbackURL, { // Use ignoreSearch as a shortcut to work with precached URLs // that have _WB_REVISION parameters. ignoreSearch: true, }); } }