Use WebView para disponibilizar um aplicativo da Web ou uma página da Web como parte de um
app cliente. A classe WebView é uma extensão da classe View
do Android que permite mostrar páginas da Web como parte do layout da atividade. Ele
não inclui os recursos de um navegador da Web totalmente desenvolvido, como
controles de navegação ou uma barra de endereço. Por padrão, o WebView só mostra uma
página da Web.
O WebView pode ajudar você a fornecer informações no seu app que talvez precisem ser
atualizadas, como um contrato de usuário final ou um guia do usuário. No app Android,
você pode criar uma Activity que contenha um
WebView e usá-la para exibir o documento hospedado on-line.
O WebView também pode ajudar quando o app fornece ao usuário dados que exigem uma
conexão de Internet para serem recuperados, como e-mails. Nesse caso, pode ser
mais fácil criar um WebView no app Android que mostre uma página da Web
com todos os dados do usuário, em vez de realizar uma solicitação de rede, analisar
os dados e renderizá-los em um layout do Android. Em vez disso, você pode criar
uma página da Web personalizada para dispositivos Android e implementar uma
WebView no app Android que carregue a página da Web.
Este documento descreve como começar a usar o WebView, como vincular
o JavaScript da sua página da Web ao código do lado do cliente no app Android, como
processar a navegação nas páginas e como gerenciar janelas ao usar o WebView.
Trabalhar com o WebView em versões anteriores do Android
Para usar com segurança os recursos mais recentes do WebView no dispositivo em que o app está
em execução, adicione a biblioteca Jetpack Webkit. Essa é uma biblioteca estática que
pode ser adicionada ao aplicativo para usar APIs android.webkit que não estão disponíveis
para versões anteriores da plataforma.
Adicione-o ao arquivo build.gradle da seguinte maneira:
Kotlin
dependencies { implementation("androidx.webkit:webkit:1.8.0") }
Groovy
dependencies { implementation ("androidx.webkit:webkit:1.8.0") }
Confira o exemplo de WebView no GitHub para mais detalhes.
Adicionar um WebView ao app
Para adicionar um WebView ao app, inclua o elemento <WebView> no layout da atividade ou defina toda a janela Activity como um WebView em onCreate.
Adicionar uma WebView no layout da atividade
Para adicionar um WebView ao app no layout, adicione o seguinte código ao arquivo XML de layout da atividade:
<WebView android:id="@+id/webview" android:layout_width="match_parent" android:layout_height="match_parent" />
Para carregar uma página da Web no WebView, use loadUrl, conforme mostrado no
exemplo a seguir:
Kotlin
val myWebView: WebView = findViewById(R.id.webview) myWebView.loadUrl("http://www.example.com")
Java
WebView myWebView = (WebView) findViewById(R.id.webview); myWebView.loadUrl("http://www.example.com");
Adicionar um WebView em onCreate()
Para adicionar um WebView ao app no método onCreate() de uma atividade, use
uma lógica semelhante a esta:
Kotlin
val myWebView = WebView(activityContext) setContentView(myWebView)
Java
WebView myWebView = new WebView(activityContext); setContentView(myWebView);
Em seguida, carregue a página:
Kotlin
myWebView.loadUrl("http://www.example.com")
Java
myWebView.loadUrl("https://www.example.com");
Ou carregue o URL a partir de uma string HTML:
Kotlin
// Create an unencoded HTML string, then convert the unencoded HTML string into // bytes. Encode it with base64 and load the data. val unencodedHtml = "<html><body>'%23' is the percent code for ‘#‘ </body></html>"; val encodedHtml = Base64.encodeToString(unencodedHtml.toByteArray(), Base64.NO_PADDING) myWebView.loadData(encodedHtml, "text/html", "base64")
Java
// Create an unencoded HTML string, then convert the unencoded HTML string into // bytes. Encode it with base64 and load the data. String unencodedHtml = "<html><body>'%23' is the percent code for ‘#‘ </body></html>"; String encodedHtml = Base64.encodeToString(unencodedHtml.getBytes(), Base64.NO_PADDING); myWebView.loadData(encodedHtml, "text/html", "base64");
O app precisa ter acesso à Internet. Para ter acesso à Internet, solicite a permissão INTERNET no arquivo de manifesto, conforme mostrado no exemplo a seguir:
<manifest ... > <uses-permission android:name="android.permission.INTERNET" /> ... </manifest>
Para personalizar o WebView, faça o seguinte:
- Ativar o suporte à tela cheia usando
WebChromeClient. Essa classe também é chamada quando umWebViewprecisa de permissão para alterar a IU do app host, como criar ou fechar janelas ou enviar caixas de diálogo JavaScript para o usuário. Para saber mais sobre depuração nesse contexto, leia Depurar apps da Web. - Processar eventos que afetam a renderização de conteúdo, como erros em envios de formulários ou navegação usando
WebViewClient. Também é possível usar essa subclasse para interceptar o carregamento de URLs. - Ativar o JavaScript modificando
WebSettings. - Usar JavaScript para acessar objetos do framework do Android que você injetou
em um
WebView.
Usar JavaScript no WebView
Se a página da Web que você quer carregar no WebView usa JavaScript, é necessário
ativar o JavaScript para o WebView. Depois de ativar o JavaScript, você pode
criar interfaces entre o código do app e o código JavaScript.
Ativar o JavaScript
Por padrão, o JavaScript fica desativado em uma WebView. É possível ativá-lo pelo
WebSettings anexado ao WebView. Recupere WebSettings com
getSettings e ative o JavaScript com
setJavaScriptEnabled.
Confira este exemplo:
Kotlin
val myWebView: WebView = findViewById(R.id.webview) myWebView.settings.javaScriptEnabled = true
Java
WebView myWebView = (WebView) findViewById(R.id.webview); WebSettings webSettings = myWebView.getSettings(); webSettings.setJavaScriptEnabled(true);
O WebSettings oferece acesso a várias outras configurações que podem ser
úteis. Por exemplo, se você estiver desenvolvendo um aplicativo da Web projetado
especificamente para o WebView no seu app Android, defina uma string de user agent
personalizada com setUserAgentString e consulte o user agent
personalizado na sua página da Web para verificar se o cliente que solicita a página da Web é
seu app Android.
Vincular o código JavaScript ao código Android
Ao desenvolver um aplicativo da web projetado especificamente para o WebView
no seu app Android, é possível criar interfaces entre o código JavaScript e
o código Android do lado do cliente. Por exemplo, o código JavaScript pode chamar um método no
código Android para mostrar um Dialog, em vez de usar a função
alert() do JavaScript.
Para vincular uma nova interface entre o código JavaScript e o Android, chame
addJavascriptInterface, transmitindo uma instância de classe para vincular ao
JavaScript e um nome de interface que o JavaScript pode chamar para acessar a
classe.
Para saber mais sobre a comunicação entre o JavaScript e o código nativo, incluindo APIs mais modernas e seguras, consulte Acessar APIs nativas com o JSBridge.
Por exemplo, você pode incluir a seguinte classe no app para Android:
Kotlin
/** Instantiate the interface and set the context. */ class WebAppInterface(private val mContext: Context) { /** Show a toast from the web page. */ @JavascriptInterface fun showToast(toast: String) { Toast.makeText(mContext, toast, Toast.LENGTH_SHORT).show() } }
Java
public class WebAppInterface { Context mContext; /** Instantiate the interface and set the context. */ WebAppInterface(Context c) { mContext = c; } /** Show a toast from the web page. */ @JavascriptInterface public void showToast(String toast) { Toast.makeText(mContext, toast, Toast.LENGTH_SHORT).show(); } }
Neste exemplo, a classe WebAppInterface permite que a página da Web crie uma mensagem Toast usando o método showToast().
É possível vincular essa classe ao JavaScript executado no WebView com
addJavascriptInterface(), como mostrado no exemplo a seguir:
Kotlin
val webView: WebView = findViewById(R.id.webview) webView.addJavascriptInterface(WebAppInterface(this), "Android")
Java
WebView webView = (WebView) findViewById(R.id.webview); webView.addJavascriptInterface(new WebAppInterface(this), "Android");
Isso cria uma interface chamada Android para o JavaScript em execução no
WebView. Neste ponto, seu aplicativo da Web tem acesso à classe WebAppInterface. Por exemplo, veja um código HTML e JavaScript que
cria uma mensagem de aviso usando a nova interface quando o usuário toca em um botão:
<input type="button" value="Say hello" onClick="showAndroidToast('Hello Android!')" /> <script type="text/javascript"> function showAndroidToast(toast) { Android.showToast(toast); } </script>
Não é necessário inicializar a interface Android do JavaScript. O
WebView o disponibiliza automaticamente para sua página da Web. Assim, quando um usuário
toca no botão, a função showAndroidToast() usa a interface Android
para chamar o método WebAppInterface.showToast().
Processar a navegação nas páginas
Quando o usuário toca em um link de uma página da Web no seu WebView, por padrão, o Android
inicia um app que processa URLs. Normalmente, o navegador da Web padrão abre e
carrega o URL de destino. No entanto, é possível modificar esse comportamento
WebView para que os links sejam abertos no WebView. Em seguida, você pode permitir que o usuário
navegue para trás e para frente no histórico de páginas da Web mantido
pelo WebView.
Para abrir links tocados pelo usuário, forneça um WebViewClient para seu WebView
usando setWebViewClient. Todos os links que o usuário tocar serão carregados na
WebView. Se você quiser mais controle sobre onde um link clicado é carregado, crie seu
próprio WebViewClient que substitua o método
shouldOverrideUrlLoading. O exemplo a seguir pressupõe que MyWebViewClient é uma classe interna
de Activity.
Kotlin
private class MyWebViewClient : WebViewClient() { override fun shouldOverrideUrlLoading(view: WebView?, url: String?): Boolean { if (Uri.parse(url).host == "www.example.com") { // This is your website, so don't override. Let your WebView load // the page. return false } // Otherwise, the link isn't for a page on your site, so launch another // Activity that handles URLs. Intent(Intent.ACTION_VIEW, Uri.parse(url)).apply { startActivity(this) } return true } }
Java
private class MyWebViewClient extends WebViewClient { @Override public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) { if ("www.example.com".equals(request.getUrl().getHost())) { // This is your website, so don't override. Let your WebView load the // page. return false; } // Otherwise, the link isn't for a page on your site, so launch another // Activity that handles URLs. Intent intent = new Intent(Intent.ACTION_VIEW, request.getUrl()); startActivity(intent); return true; } }
Em seguida, crie uma instância desse novo WebViewClient para a WebView:
Kotlin
val myWebView: WebView = findViewById(R.id.webview) myWebView.webViewClient = MyWebViewClient()
Java
WebView myWebView = (WebView) findViewById(R.id.webview); myWebView.setWebViewClient(new MyWebViewClient());
Agora, quando o usuário toca em um link, o sistema chama o método shouldOverrideUrlLoading,
que verifica se o host do URL corresponde a um domínio específico, conforme definido
no exemplo anterior. Se houver correspondência, o método vai retornar "false" e
não vai substituir o carregamento do URL. Ele permite que o WebView carregue o URL normalmente.
Se o host do URL não corresponder, um Intent será criado para iniciar o
Activity padrão para processar URLs, que é resolvido para o navegador da Web padrão
do usuário.
Processar URLs personalizados
O WebView aplica restrições ao solicitar recursos e resolver links
que usam um esquema de URL personalizado. Por exemplo, se você implementar callbacks como
shouldOverrideUrlLoading ou shouldInterceptRequest, o
WebView vai invocá-los apenas para URLs válidos.
Por exemplo, o WebView pode não chamar o método shouldOverrideUrlLoading
para links como este:
<a href="showProfile">Show Profile</a>
URLs inválidos, como o mostrado no exemplo anterior, são processados de forma inconsistente no WebView. Por isso, recomendamos usar um URL bem formado.
É possível usar um esquema personalizado ou um URL HTTPS para um domínio controlado pela sua organização.
Em vez de usar uma string simples em um link, como no exemplo anterior, é possível usar um esquema personalizado como este:
<a href="example-app:showProfile">Show Profile</a>
Em seguida, processe esse URL no método shouldOverrideUrlLoading da seguinte
maneira:
Kotlin
// The URL scheme must be non-hierarchical, meaning no trailing slashes. const val APP_SCHEME = "example-app:" override fun shouldOverrideUrlLoading(view: WebView?, url: String?): Boolean { return if (url?.startsWith(APP_SCHEME) == true) { urlData = URLDecoder.decode(url.substring(APP_SCHEME.length), "UTF-8") respondToData(urlData) true } else { false } }
Java
// The URL scheme must be non-hierarchical, meaning no trailing slashes. private static final String APP_SCHEME = "example-app:"; @Override public boolean shouldOverrideUrlLoading(WebView view, String url) { if (url.startsWith(APP_SCHEME)) { urlData = URLDecoder.decode(url.substring(APP_SCHEME.length()), "UTF-8"); respondToData(urlData); return true; } return false; }
A API shouldOverrideUrlLoading é destinada principalmente ao lançamento de intents
para URLs específicos. Ao implementá-la, retorne false para URLs
processados pelo WebView. No entanto, você não se limita a iniciar intents. É possível
substituir as intents de inicialização por qualquer comportamento personalizado nos exemplos de código
anteriores.
Navegar pelo histórico de páginas da Web
Quando o WebView substitui o carregamento de URL, ele acumula automaticamente um
histórico de páginas da Web visitadas. É possível navegar para trás e para frente no
histórico com goBack e goForward.
Por exemplo, o código abaixo mostra como o Activity pode usar o botão "Voltar"
do dispositivo para navegar para trás:
Kotlin
override fun onKeyDown(keyCode: Int, event: KeyEvent?): Boolean { // Check whether the key event is the Back button and if there's history. if (keyCode == KeyEvent.KEYCODE_BACK && myWebView.canGoBack()) { myWebView.goBack() return true } // If it isn't the Back button or there isn't web page history, bubble up to // the default system behavior. Probably exit the activity. return super.onKeyDown(keyCode, event) }
Java
@Override public boolean onKeyDown(int keyCode, KeyEvent event) { // Check whether the key event is the Back button and if there's history. if ((keyCode == KeyEvent.KEYCODE_BACK) && myWebView.canGoBack()) { myWebView.goBack(); return true; } // If it isn't the Back button or there's no web page history, bubble up to // the default system behavior. Probably exit the activity. return super.onKeyDown(keyCode, event); }
Se o app usa o Jetpack AppCompat 1.6.0 ou mais recente, é possível simplificar ainda mais o snippet
anterior:
Kotlin
onBackPressedDispatcher.addCallback { // Check whether there's history. if (myWebView.canGoBack()) { myWebView.goBack() } }
Java
onBackPressedDispatcher.addCallback { // Check whether there's history. if (myWebView.canGoBack()) { myWebView.goBack(); } }
O método canGoBack vai retornar verdadeiro se houver um histórico de páginas da Web para o
usuário acessar. Da mesma forma, use canGoForward para verificar se
há um histórico de avanço. Se você não fizer essa verificação, depois que o usuário
chegar ao fim do histórico, goBack e goForward não vão fazer nada.
Para preservar o histórico de navegação durante a recriação de atividades ou a recuperação de processos
em segundo plano, use saveState para serializar o histórico de navegação do WebView
em um Bundle e restoreState para restaurá-lo.
Para orientações sobre como gerenciar com segurança os limites de tamanho do estado salvo e evitar
TransactionTooLargeException, consulte Gerenciar o estado do WebView com eficiência.
Gerenciar mudanças de configuração do dispositivo
Durante o tempo de execução, as mudanças no estado da atividade ocorrem quando a configuração de um dispositivo
muda, como quando os usuários giram o dispositivo ou dispensam um editor de método de entrada
(IME, na sigla em inglês). Essas mudanças fazem com que a atividade de um objeto WebView seja destruída e uma
nova atividade seja criada, o que também cria um novo objeto WebView que carrega
o URL do objeto destruído. Você pode usar saveState em
onSaveInstanceState() e restoreState após a recriação para restaurar
o contexto de navegação do usuário. Para estratégias de gerenciamento seguro do tamanho do estado,
consulte Gerenciar o estado do WebView com eficiência.
Para modificar o comportamento padrão da atividade, mude como ela processa as mudanças de
orientation no manifesto. Para saber mais sobre como processar
mudanças de configuração durante a execução, leia Processar mudanças de configuração.
Gerenciar janelas
Por padrão, as solicitações para abrir novas janelas são ignoradas. Isso é válido se elas
são abertas pelo JavaScript ou pelo atributo de destino em um link. É possível personalizar
o WebChromeClient para fornecer seu próprio comportamento ao abrir várias
janelas.
Para manter o app mais seguro, é melhor impedir que pop-ups e novas janelas sejam
abertos. A maneira mais segura de implementar esse comportamento é transmitir "true" para
setSupportMultipleWindows, mas não substituir o
método onCreateWindow, de que setSupportMultipleWindows() depende.
Essa lógica impede que qualquer página que use target="_blank" nos links seja
carregada.
Gerenciar memória e desempenho
Como o WebView é executado em um mecanismo baseado no Chromium com processos separados e
código nativo, o uso da memória de referência é maior do que as visualizações padrão do Android.
Reutilizar instâncias de WebView e destruí-las corretamente é essencial para
manter um app estável.
Para mais informações sobre como diagnosticar e otimizar o consumo de memória do app ao usar conteúdo da Web, consulte Gerenciar e diagnosticar a memória do WebView.