Este guia descreve os benefícios da biblioteca Jetpack Webkit, explica como ela funciona e como você pode implementá-la nos seus projetos.
Visão geral
As WebViews são uma parte essencial do desenvolvimento para Android, mas às vezes podem ser difíceis de gerenciar devido a inconsistências nos recursos em diferentes versões do SO Android. Cada versão do SO Android fornece um conjunto fixo de APIs WebView. Como o Android é lançado em uma cadência mais lenta do que a WebView, as APIs do Android podem não abranger todos os recursos disponíveis da WebView. Isso leva a uma implantação mais lenta de recursos e aumenta os custos de teste.
O Jetpack Webkit resolve esses problemas atuando como uma camada de compatibilidade e aproveitando o APK do WebView atualizado no dispositivo do usuário. Ela também contém APIs novas e modernas que estão disponíveis exclusivamente nessa biblioteca.
Por que usar o Jetpack Webkit?
Além de oferecer compatibilidade entre versões, o Jetpack Webkit também oferece APIs novas e modernas que podem simplificar o desenvolvimento e melhorar a funcionalidade do app:
Ativa a autenticação moderna: a WebView pode processar sem problemas padrões modernos de autenticação na Web, como o WebAuthn, permitindo logins com chaves de acesso. A biblioteca
androidx.webkit
oferece controle total sobre essa integração usando o métodoWebSettingsCompat.setWebAuthenticationSupport()
, que pode ser usado para configurar o nível de suporte necessário para seu app.Melhora a performance: ajuste a performance da WebView para os casos de uso do seu app usando APIs como
prefetchUrlAsync
,prerenderUrlAsync
esetBackForwardCacheEnabled
.Aumenta a estabilidade: recupera processos de renderização parados ou sem resposta sem falhas. Para mais informações, consulte
WebViewRenderProcess#terminate()
:Oferece controle granular sobre os dados de navegação: para excluir os dados de navegação armazenados pela WebView para origens específicas, use a classe
WebStorageCompat
.
Entenda os componentes
Para usar o Jetpack Webkit de maneira eficaz, é necessário entender a relação entre os seguintes componentes:
WebView do sistema Android: é o mecanismo de renderização baseado no Chromium que o Google atualiza regularmente na Google Play Store na mesma cadência do Chrome. Ele contém os recursos mais atualizados e fornece o código de implementação para todas as APIs WebView.
APIs de framework (
android.webkit
): são as APIs fixadas em uma versão específica do sistema operacional Android. Por exemplo, um app no Android 10 só pode acessar as APIs disponíveis quando essa versão foi lançada. Portanto, ele não pode usar novos recursos adicionados ao APK WebView em atualizações mais recentes. Por exemplo, para controlar um renderizador sem resposta comWebView#getWebViewRenderProcess()
, só é possível chamar isso no Android 10 e versões mais recentes.Biblioteca Jetpack Webkit (
androidx.webkit
): é uma pequena biblioteca agrupada no seu aplicativo. Essa biblioteca atua como uma ponte que chama o APK WebView, em vez de chamar as APIs definidas na plataforma Android, que tem uma versão fixa do SO. Assim, mesmo quando um aplicativo é instalado em um dispositivo com uma versão mais antiga do SO, como o Android 10, ele pode usar os recursos mais recentes da WebView. Por exemplo,WebViewCompat.getWebViewRenderProcess()
funciona de maneira semelhante à API do framework, mas também pode ser chamada em todas as versões do SO anteriores ao Android 10.
Se uma API estiver disponível no framework e no Jetpack Webkit, recomendamos que você escolha a versão do Jetpack Webkit. Isso ajuda a garantir um comportamento e uma compatibilidade consistentes no maior número possível de dispositivos.
Interação entre o Webkit do Jetpack e o APK
As APIs no Jetpack Webkit são implementadas em duas partes:
WebKit estático do Jetpack: a biblioteca estática do WebKit do Jetpack contém uma minoria do código responsável por implementar a API.
APK do WebView: o APK do WebView contém a maior parte do código.
Seu app chama a API Jetpack Webkit, que chama o APK WebView.
Embora você controle a versão do Jetpack Webkit no seu app, não é possível controlar as atualizações do APK do WebView nos dispositivos dos usuários. Em geral, a maioria dos usuários tem versões atualizadas do APK do WebView, mas seu app ainda precisa ter cuidado para não chamar APIs que essa versão específica do APK do WebView não oferece suporte.
O Jetpack Webkit também elimina a necessidade de verificar manualmente as versões do WebView.
Para determinar se um recurso está disponível, verifique a constante dele. Por
exemplo, WebViewFeature.WEB_AUTHENTICATION
.
Como eles funcionam juntos
O Jetpack Webkit preenche a lacuna entre a API Framework estática e o APK WebView atualizado com frequência. Ao usar a API Jetpack Webkit com o padrão de detecção de recursos, a biblioteca realiza uma verificação para saber se o recurso é compatível com o APK WebView instalado no dispositivo do usuário. Isso oferece o benefício de não precisar verificar a versão do SO Android (framework).
Se o APK do WebView for uma versão recente, a biblioteca vai invocar o recurso. Caso contrário, ele informa que o recurso não está disponível, evitando que o app falhe e permitindo que você lide com a situação de maneira adequada.
Comparar APIs do Jetpack Webkit e do framework
Esta seção compara métodos de implementação com e sem a biblioteca Jetpack Webkit:
Ativar a autenticação moderna (WebAuthn)
Sem o Jetpack Webkit
Não é possível usar APIs de framework.
Com o Jetpack Webkit
Usa WebViewFeature.WEB_AUTHENTICATION
para verificações de compatibilidade.
if (WebViewFeature.isFeatureSupported(WebViewFeature.WEB_AUTHENTICATION)) {
WebSettingsCompat.setWebAuthenticationSupport(
webView.settings,
WebSettingsCompat.WEB_AUTHENTICATION_SUPPORT_FOR_APP
)
}
Excluir dados de uma origem (armazenamento específico do site)
Sem o Jetpack WebKit
Não há uma API direta para limpar dados de origem específicos. Muitas vezes, é necessário limpar todos os dados.
Com o Jetpack WebKit
Usa APIs de compatibilidade para exclusão precisa de dados. É possível usar uma das seguintes opções:
WebStorageCompat.getInstance().deleteBrowsingData()
Ou
WebStorageCompat.getInstance().deleteBrowsingDataForSite()
Acessar a versão do WebView
Sem o Jetpack WebKit
Usa a classe de framework padrão.
val webViewPackage = WebView.getCurrentWebViewPackage()
Com o Jetpack WebKit
Usa a camada de compatibilidade para uma recuperação mais segura.
val webViewPackage = WebViewCompat.getCurrentWebViewPackage()
Lidar com renderizador sem resposta (cliente renderizador)
Sem o Jetpack WebKit
Usa o método padrão do framework.
webView.setWebViewRenderProcessClient(myClient)
Com o Jetpack WebKit
Usa WebViewCompat e uma verificação de recursos para definir o cliente.
if (WebViewFeature.isFeatureSupported(WebViewFeature.WEB_VIEW_RENDERER_CLIENT_BASIC_USAGE)) {
WebViewCompat.setWebViewRenderProcessClient(webView, myClient)
}
Para mais informações, consulte a documentação de referência do androidx.webkit
.
Integrar o Jetpack Webkit ao seu código
O uso do Jetpack Webkit aumenta os recursos da classe WebView padrão, mas não substitui totalmente a classe WebView original.
Você pode continuar usando a classe android.webkit.WebView
. Você pode adicioná-lo aos layouts XML e receber uma referência à instância no seu código. Para
acessar recursos padrão do framework, ainda é possível chamar métodos diretamente na
instância do WebView ou no objeto de configurações dela.
Para acessar recursos modernos, use os métodos auxiliares estáticos fornecidos pelo
Jetpack Webkit, como WebViewCompat
e WebSettingsCompat
. Você
transmite sua instância WebView atual para esses métodos.
Kotlin
import android.webkit.WebView
import androidx.webkit.WebSettingsCompat
import androidx.webkit.WebViewFeature
// You still get your WebView instance the standard way.
val webView: WebView = findViewById(R.id.my_webview)
// To enable a modern feature, you pass that instance to a Jetpack Webkit helper.
if (WebViewFeature.isFeatureSupported(WebViewFeature.FORCE_DARK)) {
WebSettingsCompat.setForceDark(webView.settings, WebSettingsCompat.FORCE_DARK_ON)
}
Java
import android.webkit.WebView;
import androidx.webkit.WebSettingsCompat;
import androidx.webkit.WebViewFeature;
// You still get your WebView instance the standard way.
WebView webView = findViewById(R.id.my_webview);
// To enable a modern feature, you pass that instance to a Jetpack Webkit helper.
if (WebViewFeature.isFeatureSupported(WebViewFeature.FORCE_DARK)) {
WebSettingsCompat.setForceDark(webView.settings, WebSettingsCompat.FORCE_DARK_ON);
}
Implementar o Jetpack Webkit
Para implementar o Jetpack Webkit, use o procedimento a seguir.
Etapa 1: adicionar a dependência
No arquivo build.gradle.kts
ou build.gradle
do módulo, inclua a
dependência a seguir para adicionar o Jetpack Webkit:
Groovy
dependencies { implementation "androidx.webkit:webkit:1.14.0" }
Kotlin
dependencies { implementation("androidx.webkit:webkit:1.14.0") }
O Jetpack Webkit contém wrappers leves, então o impacto no tamanho do aplicativo é mínimo.
Etapa 2: adotar o padrão de detecção de recursos
Para evitar falhas ao invocar APIs indisponíveis, use verificações de recursos. Recomendamos envolver cada invocação de API com uma verificação de recurso e considerar uma lógica de substituição para quando a API estiver indisponível.
Recomendamos o seguinte padrão para usar uma API WebView moderna:
import android.webkit.WebView
import androidx.webkit.WebSettingsCompat
import androidx.webkit.WebViewFeature
// In your Kotlin code where you configure your WebView
val webView: WebView = findViewById(R.id.my_webview)
// Before you use a modern API, first check if it is supported.
if (WebViewFeature.isFeatureSupported(WebViewFeature.FORCE_DARK)) {
// If the check passes, it is safe to call the API.
WebSettingsCompat.setForceDark(webView.settings, WebSettingsCompat.FORCE_DARK_ON)
} else {
// Optionally, provide a fallback for older WebView versions.
}
Esse padrão ajuda a garantir que o aplicativo seja robusto. Como a verificação de recursos
é executada primeiro, o aplicativo não falha se o recurso não estiver disponível. A sobrecarga de desempenho da verificação WebViewFeature#isFeatureSupported()
é insignificante.