Gepubliceerd: 2 december 2020
Sinds de introductie van Trusted Web Activity heeft het Chrome-team het gebruik ervan met Bubblewrap eenvoudiger gemaakt. We hebben extra functies toegevoegd, zoals Google Play Billing-integratie , en ervoor gezorgd dat deze op meer platforms kan werken, zoals ChromeOS .
Bubblewrap- en Trusted Web Activity-functies
Met Bubblewrap kunt u apps maken die uw PWA's starten binnen een vertrouwde webactiviteit, zonder dat u kennis van platformspecifieke tools nodig heeft.
Vereenvoudigde installatiestroom
Voorheen vereiste het gebruik van Bubblewrap het handmatig instellen van de Java Development Kit en de Android SDK, die beide foutgevoelig zijn. De tool biedt nu de mogelijkheid om de externe afhankelijkheden automatisch te downloaden wanneer deze voor de eerste keer wordt uitgevoerd.
U kunt er nog steeds voor kiezen om een bestaande installatie van de afhankelijkheden te gebruiken, als u dat liever doet, en het nieuwe doctor
-commando helpt bij het vinden van problemen en beveelt oplossingen aan voor de configuratie, die nu kan worden bijgewerkt vanaf de opdrachtregel met behulp van de opdracht updateConfig
.
Verbeterde tovenaar
Bij het maken van een project met init
heeft Bubblewrap informatie nodig om de Android-app te genereren. De tool haalt waarden uit het Web App Manifest en biedt waar mogelijk standaardwaarden.
U kunt deze waarden wijzigen wanneer u een nieuw project aanmaakt, maar voorheen was de betekenis van elk veld niet duidelijk. De initialisatiedialogen zijn opnieuw opgebouwd met betere beschrijvingen en validatie voor elk invoerveld.
Weergave op volledig scherm en ondersteuning voor oriëntatie
In sommige gevallen wilt u misschien dat uw applicatie een zo groot mogelijk deel van het scherm gebruikt. Bij het bouwen van PWA's wordt dit geïmplementeerd door het display
van het Web App Manifest in te stellen op fullscreen
.
Wanneer Bubblewrap de optie voor volledig scherm in het Web App Manifest detecteert, wordt de Android-applicatie geconfigureerd om ook op volledig scherm of in meeslepende modus te starten, in Android-specifieke termen.
Het orientation
van het Web App Manifest definieert of de applicatie moet worden gestart in portretmodus, landschapsmodus of in de oriëntatie die het apparaat momenteel gebruikt. Bubblewrap leest nu het veld Web App Manifest en gebruikt dit standaard bij het maken van de Android-app.
U kunt beide configuraties aanpassen als onderdeel van de bubblewrap init
stroom.
AppBundles-uitvoer
App Bundles is een publicatieformaat voor apps dat de uiteindelijke APK-generatie en ondertekening delegeert aan Play. Hierdoor kunnen in de praktijk kleinere bestanden aan gebruikers worden aangeboden bij het downloaden van de app uit de store.
Bubblewrap verpakt de applicatie nu als een app-bundel, in een bestand met de naam app-release-bundle.aab
. U zou de voorkeur moeten geven aan dit formaat wanneer u apps publiceert in de Play Store, aangezien dit vanaf 2021 door de winkel vereist is.
Delegatie van geolocatie
Gebruikers verwachten dat applicaties die op hun apparaten zijn geïnstalleerd zich consistent gedragen, ongeacht de technologie. Bij gebruik binnen een vertrouwde webactiviteit kan de toestemming voor GeoLocation nu worden gedelegeerd aan het besturingssysteem en, indien ingeschakeld, zien gebruikers dezelfde dialoogvensters als apps die zijn gebouwd met Kotlin of Java, en vinden ze bedieningselementen om de toestemming op dezelfde plaats te beheren.
De functie kan worden toegevoegd via Bubblewrap en omdat het extra afhankelijkheden aan het Android-project toevoegt, moet u deze alleen inschakelen als de webapp de toestemming voor geolocatie gebruikt.
Geoptimaliseerde binaire bestanden
Apparaten met beperkte opslagruimte zijn gebruikelijk in bepaalde delen van de wereld, en eigenaren van dergelijke apparaten geven vaak de voorkeur aan kleinere toepassingen. Applicaties die Trusted Web Activity gebruiken, produceren kleine binaire bestanden, waardoor een deel van de angst bij deze gebruikers wordt weggenomen.
Bubblewrap is geoptimaliseerd door de lijst met benodigde Android-bibliotheken te verkleinen, wat resulteert in gegenereerde binaire bestanden die 800k kleiner zijn. In de praktijk is dat minder dan de helft van de gemiddelde grootte van eerdere versies. Om te profiteren van de kleinere binaire bestanden, hoeft u uw app alleen maar bij te werken met de nieuwste versie van Bubblewrap.
Hoe u een bestaande app kunt updaten
Een door Bubblewrap gegenereerde applicatie bestaat uit een webapplicatie en een lichtgewicht Android-wrapper die de PWA opent. Hoewel de PWA die in een vertrouwde webactiviteit wordt geopend, dezelfde updatecycli volgt als elke andere webapp, kan en moet de native wrapper worden bijgewerkt.
U moet uw app bijwerken om er zeker van te zijn dat deze de nieuwste versie van de wrapper gebruikt, met de nieuwste bugfixes en functies. Als de nieuwste versie van Bubblewrap is geïnstalleerd, past de opdracht update
de nieuwste versie van de wrapper toe op een bestaand project:
npm update -g @bubblewrap/cli
bubblewrap update
bubblewrap build
Een andere reden om deze applicaties bij te werken is ervoor te zorgen dat wijzigingen in het webmanifest op de applicatie worden toegepast. Gebruik daarvoor het nieuwe merge
commando:
bubblewrap merge
bubblewrap update
bubblewrap build
Updates van de kwaliteitscriteria
Chrome 86 heeft wijzigingen geïntroduceerd in de kwaliteitscriteria voor vertrouwde webactiviteiten, die volledig worden uitgelegd in Wijzigingen in kwaliteitscriteria voor PWA's die vertrouwde webactiviteit gebruiken .
Een korte samenvatting is dat u ervoor moet zorgen dat uw toepassingen met de volgende scenario's omgaan om te voorkomen dat ze crashen:
- Kan de koppelingen naar digitale middelen niet verifiëren bij het starten van de applicatie
- Kan HTTP 200 niet retourneren voor een offline netwerkbronverzoek
- Terugkeer van een HTTP 404- of 5xx-fout in de applicatie.
Naast dat de applicatie de validatie van Digital Asset Links doorstaat, kunnen de overige scenario's door een servicemedewerker worden afgehandeld:
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 bakt volgens de beste praktijken en verwijdert standaardwerk bij het gebruik van servicemedewerkers. U kunt ook overwegen een Workbox-plug-in te gebruiken om deze scenario's af te handelen:
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,
});
}
}