Veröffentlicht: 2. Dezember 2020
Seit der Einführung von Trusted Web Activity hat das Chrome-Team die Verwendung mit Bubblewrap vereinfacht. Wir haben zusätzliche Funktionen hinzugefügt, z. B. die Google Play-Abrechnungsintegration, und die Funktion auf mehr Plattformen wie ChromeOS verfügbar gemacht.
Bubblewrap und vertrauenswürdige Web-Aktivitäten
Mit Bubblewrap können Sie Apps erstellen, die Ihre PWAs in einer Trusted Web Activity starten, ohne dass Sie sich mit plattformspezifischen Tools auskennen müssen.
Vereinfachte Einrichtung
Bisher mussten Sie das Java Development Kit und das Android SDK manuell einrichten, was fehleranfällig ist. Das Tool bietet jetzt die Möglichkeit, die externen Abhängigkeiten beim ersten Ausführen automatisch herunterzuladen.
Sie können weiterhin eine vorhandene Installation der Abhängigkeiten verwenden. Mit dem neuen Befehl doctor
können Sie Probleme finden und Korrekturen für die Konfiguration empfehlen, die jetzt über die Befehlszeile mit dem Befehl updateConfig
aktualisiert werden kann.
Verbesserter Assistent
Wenn Sie ein Projekt mit init
erstellen, benötigt Bubblewrap Informationen, um die Android-App zu generieren. Das Tool extrahiert Werte aus dem Web-App-Manifest und stellt nach Möglichkeit Standardwerte bereit.
Sie können diese Werte beim Erstellen eines neuen Projekts ändern. Bisher war jedoch nicht klar, was die einzelnen Felder bedeuten. Die Dialogfelder für die Initialisierung wurden mit besseren Beschreibungen und Validierungen für jedes Eingabefeld neu erstellt.
Vollbildmodus und Ausrichtung unterstützen
In einigen Fällen möchten Sie, dass Ihre Anwendung so viel wie möglich vom Bildschirm nutzt. Beim Erstellen von PWAs wird dies durch Festlegen des Felds display
im Web-App-Manifest auf fullscreen
implementiert.
Wenn Bubblewrap die Option „Vollbild“ im Web-App-Manifest erkennt, konfiguriert es die Android-Anwendung so, dass sie auch im Vollbildmodus oder, in Android-spezifischen Begriffen, im Immersive Mode gestartet wird.
Das Feld orientation
im Web-App-Manifest gibt an, ob die Anwendung im Hoch- oder Querformat oder in der aktuell auf dem Gerät verwendeten Ausrichtung gestartet werden soll. Bubblewrap liest jetzt das Manifest-Feld der Web-App und verwendet es als Standard beim Erstellen der Android-App.
Sie können beide Konfigurationen im Rahmen des bubblewrap init
-Ablaufs anpassen.
AppBundles-Ausgabe
App-Bundles ist ein Veröffentlichungsformat für Apps, bei dem die endgültige APK-Generierung und ‑Signatur an Google Play delegiert wird. In der Praxis können so beim Herunterladen der App aus dem Store kleinere Dateien an die Nutzer gesendet werden.
Bubblewrap verpackt die Anwendung jetzt als App-Bundle in einer Datei namens app-release-bundle.aab
. Sie sollten dieses Format verwenden, wenn Sie Apps im Play Store veröffentlichen, da es ab 2021 vom Play Store gefordert wird.
Delegierung der Standortbestimmung
Nutzer erwarten, dass auf ihren Geräten installierte Anwendungen unabhängig von der Technologie einheitlich funktionieren. Wenn die Berechtigung GeoLocation in einer vertrauenswürdigen Webaktivität verwendet wird, kann sie jetzt an das Betriebssystem delegiert werden. Wenn sie aktiviert ist, sehen Nutzer dieselben Dialogfelder wie bei Apps, die mit Kotlin oder Java erstellt wurden, und dieselben Steuerelemente zur Verwaltung der Berechtigung.
Die Funktion kann über Bubblewrap hinzugefügt werden. Da dadurch dem Android-Projekt zusätzliche Abhängigkeiten hinzugefügt werden, sollten Sie sie nur aktivieren, wenn die Web-App die Berechtigung „Standortermittlung“ verwendet.
Optimierte Binärdateien
Geräte mit begrenztem Speicherplatz sind in bestimmten Regionen der Welt weit verbreitet und die Nutzer dieser Geräte bevorzugen häufig kleinere Anwendungen. Anwendungen, die vertrauenswürdige Webaktivitäten verwenden, erzeugen kleine Binärdateien, was diese Bedenken etwas abmildert.
Bubblewrap wurde optimiert, indem die Liste der erforderlichen Android-Bibliotheken reduziert wurde. Dadurch sind die generierten Binärdateien 800 KB kleiner. In der Praxis entspricht das weniger als der Hälfte der durchschnittlichen Größe, die mit früheren Versionen generiert wurde. Wenn Sie die kleineren Binärdateien nutzen möchten, müssen Sie Ihre App nur mit der neuesten Version von Bubblewrap aktualisieren.
Vorhandene App aktualisieren
Eine von Bubblewrap generierte Anwendung besteht aus einer Webanwendung und einem schlanken Android-Wrapper, der die PWA öffnet. Auch wenn die PWA, die in einer vertrauenswürdigen Web-Aktivität geöffnet wird, denselben Aktualisierungszyklen wie jede andere Webanwendung folgt, kann und sollte der native Wrapper aktualisiert werden.
Sie sollten Ihre App aktualisieren, damit die neueste Version des Wrappers mit den neuesten Fehlerkorrekturen und Funktionen verwendet wird. Wenn die neueste Version von Bubblewrap installiert ist, wird mit dem Befehl update
die neueste Version des Wrappers auf ein vorhandenes Projekt angewendet:
npm update -g @bubblewrap/cli
bubblewrap update
bubblewrap build
Ein weiterer Grund für die Aktualisierung dieser Anwendungen besteht darin, dafür zu sorgen, dass Änderungen am Web-Manifest auf die Anwendung angewendet werden. Verwenden Sie dazu den neuen Befehl merge
:
bubblewrap merge
bubblewrap update
bubblewrap build
Aktualisierung der Qualitätskriterien
In Chrome 86 wurden Änderungen an den Qualitätskriterien für vertrauenswürdige Web-Aktivitäten eingeführt. Weitere Informationen finden Sie unter Änderungen der Qualitätskriterien für PWAs mit vertrauenswürdiger Web-Aktivität.
Kurz gesagt: Sie sollten dafür sorgen, dass Ihre Anwendungen die folgenden Szenarien verarbeiten, um Abstürze zu vermeiden:
- Digital Asset Links konnten bei der App-Veröffentlichung nicht bestätigt werden
- HTTP 200 wird nicht für eine Anfrage an eine Offline-Netzwerkressource zurückgegeben
- In der Anwendung wird ein HTTP-404- oder 5xx-Fehler zurückgegeben.
Neben der Prüfung, ob die Anwendung die Validierung von Digital Asset Links besteht, können die verbleibenden Szenarien von einem Service Worker verarbeitet werden:
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 enthält Best Practices und entfernt Boilerplate-Code bei der Verwendung von Dienstarbeitern. Alternativ können Sie ein Workbox-Plug-in verwenden, um diese Szenarien zu verarbeiten:
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,
});
}
}