Użyj WebView
do dostarczania aplikacji internetowej
lub stronę internetową jako część aplikacji klienckiej. Klasa WebView
jest rozszerzeniem klasy View
w Androidzie, która umożliwia wyświetlanie stron internetowych w ramach układu aktywności. Nie zawiera ona funkcji
funkcje w pełni opracowanej przeglądarki, takie jak elementy sterujące nawigacji czy
pasku adresu. Domyślnie WebView
wyświetla tylko stronę internetową.
WebView
może Ci pomóc udostępniać w aplikacji informacje, których możesz potrzebować
np. umowę użytkownika lub przewodnik użytkownika. W aplikacji na Androida
możesz utworzyć obiekt Activity
zawierający
WebView
, a następnie użyj go, aby wyświetlić dokument, który jest przechowywany online.
WebView
może się też przydać, gdy Twoja aplikacja udostępnia dane użytkownikowi, który wymaga podania danych
połączenie z internetem w celu pobrania danych, np. e-maili. W takim przypadku łatwiej może być utworzyć w aplikacji na Androida element WebView
, który wyświetla stronę internetową ze wszystkimi danymi użytkownika, zamiast wysyłać żądanie sieciowe, a następnie analizować dane i renderować je w układzie Androida. Zamiast tego możesz zaprojektować stronę internetową dostosowaną do urządzeń z Androidem, a potem wdrożyć w aplikacji na Androida element WebView
, który wczytuje tę stronę.
W tym dokumencie znajdziesz informacje o tym, jak zacząć korzystać z WebView
, jak powiązać kod JavaScript ze strony internetowej z kodem po stronie klienta w aplikacji na Androida, jak obsługiwać nawigację po stronach oraz jak zarządzać oknami podczas korzystania z WebView
.
Korzystanie z komponentu WebView we wcześniejszych wersjach Androida
Aby bezpiecznie korzystać z najnowszych funkcji WebView
na urządzeniu, na którym jest Twoja aplikacja
dodaj aplikację AndroidX
z biblioteki Webkit. Jest to statyczna biblioteka, którą możesz dodać do aplikacji, aby korzystać z interfejsów API android.webkit
, które nie są dostępne w starszych wersjach platformy.
Dodaj go do pliku build.gradle
w ten sposób:
dependencies { implementation("androidx.webkit:webkit:1.8.0") }
dependencies { implementation ("androidx.webkit:webkit:1.8.0") }
Aby dowiedzieć się więcej, zapoznaj się z przykładem WebView
w GitHub.
Dodawanie komponentu WebView do aplikacji
Aby dodać WebView
do swojej aplikacji, możesz umieścić element <WebView>
w swojej aplikacji
układ aktywności lub ustaw całe okno Activity
jako WebView
onCreate()
Dodawanie komponentu WebView w układzie aktywności
Aby dodać WebView
do swojej aplikacji w układzie, dodaj ten kod do
pliku XML układu aktywności:
<WebView android:id="@+id/webview" android:layout_width="match_parent" android:layout_height="match_parent" />
Aby wczytać stronę internetową w komponencie WebView
, użyj elementu loadUrl()
, jak w tym przykładzie:
val myWebView: WebView = findViewById(R.id.webview) myWebView.loadUrl("http://www.example.com")
WebView myWebView = (WebView) findViewById(R.id.webview); myWebView.loadUrl("http://www.example.com");
Dodawanie WebView w metodzie onCreate()
Aby zamiast tego dodać WebView
do aplikacji w metodzie onCreate()
aktywności, użyj
w podobny sposób:
val myWebView = WebView(activityContext) setContentView(myWebView)
WebView myWebView = new WebView(activityContext); setContentView(myWebView);
Następnie otwórz stronę:
myWebView.loadUrl("http://www.example.com")
myWebView.loadUrl("https://www.example.com");
Możesz też wczytać adres URL z ciągu HTML:
// 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")
// 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");
Aplikacja musi mieć dostęp do internetu. Aby uzyskać dostęp do internetu, w pliku manifestu poproś o przyznanie uprawnienia INTERNET
, jak w tym przykładzie:
<manifest ... > <uses-permission android:name="android.permission.INTERNET" /> ... </manifest>
Aby dostosować WebView
, wykonaj jedną z tych czynności:
- Włączanie obsługi pełnego ekranu za pomocą
WebChromeClient
. Te zajęcia jest również wywoływane, gdy usługaWebView
potrzebuje uprawnień do modyfikowania interfejsu użytkownika aplikacji hosta. na przykład przez tworzenie lub zamykanie okien czy wysyłanie okien dialogowych JavaScript do użytkownika. Więcej informacji o debugowaniu w tym kontekście znajdziesz w artykule Debugowanie sieci - Postępowanie w przypadku zdarzeń, które mają wpływ na renderowanie treści, takich jak błędy w formularzu.
lub nawigacji za pomocą
WebViewClient
Możesz też użyć tę podklasę do przechwytywania wczytywania adresu URL. - Włączanie języka JavaScript przez wprowadzenie zmian
WebSettings
- Używanie JavaScriptu do uzyskiwania dostępu do obiektów platformy Androida, które zostały wstrzyknięte do
WebView
.
Używanie JavaScriptu w komponencie WebView
Jeśli strona internetowa, którą chcesz wczytać w interfejsie WebView
, korzysta z JavaScriptu, musisz
włączyć JavaScript na urządzeniu WebView
. Po włączeniu JavaScript możesz tworzyć interfejsy między kodem aplikacji a kodem JavaScript.
Włącz obsługę języka JavaScript
Domyślnie JavaScript jest wyłączony w WebView
. Aby ją włączyć, użyj
Urządzenie WebSettings
zostało podłączone do urządzenia WebView
. Pobierz WebSettings
za pomocą getSettings()
, a potem włącz JavaScript za pomocą setJavaScriptEnabled()
.
Zobacz ten przykład:
val myWebView: WebView = findViewById(R.id.webview) myWebView.settings.javaScriptEnabled = true
WebView myWebView = (WebView) findViewById(R.id.webview); WebSettings webSettings = myWebView.getSettings(); webSettings.setJavaScriptEnabled(true);
WebSettings
zapewnia dostęp do wielu innych ustawień, które mogą Ci się przydać. Jeśli na przykład tworzysz aplikację internetową zaprojektowaną
specjalnie dla WebView
w Twojej aplikacji na Androida, możesz zdefiniować
ciąg znaków klienta użytkownika z
setUserAgentString()
wysyła zapytanie do niestandardowego klienta użytkownika na stronie internetowej,
żądania strony to aplikacja na Androida.
Wiązanie kodu JavaScript z kodem Androida
Podczas tworzenia aplikacji internetowej zaprojektowanej specjalnie pod kątem urządzeń z systemem WebView
w aplikacji na Androida, możesz tworzyć interfejsy między kodem JavaScript
kodu Androida po stronie klienta. Kod JavaScript może na przykład wywołać metodę w kodzie Androida, aby wyświetlić Dialog
, zamiast używać funkcji alert()
w JavaScript.
Aby powiązać nowy interfejs między kodem JavaScript a kodem Androida, wywołaj funkcję addJavascriptInterface()
, przekazując jej instancję klasy do powiązania z JavaScriptem i nazwę interfejsu, do którego JavaScript może się odwoływać, aby uzyskać dostęp do klasy.
W aplikacji na Androida możesz na przykład użyć tej klasy:
/** 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() } }
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(); } }
W tym przykładzie klasa WebAppInterface
umożliwia stronie internetowej tworzenie wiadomości Toast
za pomocą metody showToast()
.
Możesz powiązać tę klasę z kodem JavaScript, który działa w Twoim WebView
, za pomocą funkcji addJavascriptInterface()
, jak pokazano w tym przykładzie:
val webView: WebView = findViewById(R.id.webview) webView.addJavascriptInterface(WebAppInterface(this), "Android")
WebView webView = (WebView) findViewById(R.id.webview); webView.addJavascriptInterface(new WebAppInterface(this), "Android");
Spowoduje to utworzenie interfejsu o nazwie Android
dla JavaScriptu uruchomionego w
WebView
W tym momencie aplikacja internetowa ma dostęp do
WebAppInterface
zajęcia. Oto kilka kodów HTML i JavaScript, które
tworzy powiadomienie z nowym interfejsem, gdy użytkownik kliknie przycisk:
<input type="button" value="Say hello" onClick="showAndroidToast('Hello Android!')" /> <script type="text/javascript"> function showAndroidToast(toast) { Android.showToast(toast); } </script>
Nie musisz inicjować interfejsu Android
w JavaScript.
WebView
automatycznie udostępnia je na Twojej stronie internetowej. Gdy użytkownik
klika przycisk, funkcja showAndroidToast()
korzysta z interfejsu Android
aby wywołać metodę WebAppInterface.showToast()
.
Uchwyć nawigację po stronie
Gdy użytkownik kliknie link na stronie internetowej w urządzeniu WebView
, domyślnie na urządzeniu z Androidem
uruchamia aplikację obsługującą adresy URL. Zwykle otwierana jest domyślna przeglądarka,
wczytuje docelowy adres URL. Możesz jednak zastąpić to zachowanie w swojej aplikacji WebView
, aby linki otwierały się w niej. Następnie możesz pozwolić użytkownikowi na przechodzenie w przód i w tył po historii stron internetowych przechowywanej przez WebView
.
Aby otworzyć linki kliknięte przez użytkownika, podaj WebViewClient
dla WebView
za pomocą setWebViewClient()
.
Wszystkie linki, które użytkownik kliknie, wczytują się w Twoim WebView
. Jeśli chcesz mieć większą kontrolę nad
tam, gdzie wczytuje się kliknięty link, utwórz własny element WebViewClient
, który zastąpi
shouldOverrideUrlLoading()
. W tym przykładzie zakładamy, że MyWebViewClient
jest klasą wewnętrzną klasy Activity
.
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 } }
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; } }
Następnie utwórz instancję nowego WebViewClient
dla środowiska WebView
:
val myWebView: WebView = findViewById(R.id.webview) myWebView.webViewClient = MyWebViewClient()
WebView myWebView = (WebView) findViewById(R.id.webview); myWebView.setWebViewClient(new MyWebViewClient());
Gdy użytkownik kliknie link, system wywoła metodę shouldOverrideUrlLoading()
, która sprawdza, czy host adresu URL pasuje do określonej domeny zdefiniowanej w poprzednim przykładzie. Jeśli dane będą zgodne,
metoda zwraca wartość „false” (fałsz) i nie zastępuje wczytywania adresu URL. Pozwala to WebView
wczytać adres URL w zwykły sposób. Jeśli host adresu URL nie pasuje, tworzony jest element Intent
, który uruchamia domyślny element Activity
do obsługi adresów URL. Rozwiązuje się on do domyślnej przeglądarki internetowej użytkownika.
Obsługa niestandardowych adresów URL
WebView
stosuje ograniczenia podczas żądania zasobów i rozwiązywania linków, które używają niestandardowego schematu adresu URL. Na przykład: jeśli implementujesz wywołania zwrotne, takie jak
shouldOverrideUrlLoading()
lub
shouldInterceptRequest()
,
a następnie WebView
wywołuje je tylko dla prawidłowych adresów URL.
Na przykład funkcja WebView
może nie wywoływać metody shouldOverrideUrlLoading()
w przypadku linków takich jak:
<a href="showProfile">Show Profile</a>
Nieprawidłowe adresy URL, takie jak ten z poprzedniego przykładu, są obsługiwane
niespójnie w polu WebView
, dlatego zalecamy użycie adresu URL o prawidłowym formacie.
Możesz użyć schematu niestandardowego lub adresu URL HTTPS w domenie należącej do Twojej organizacji
elementów sterujących.
Zamiast prostego ciągu znaków w linku, jak w poprzednim przykładzie, możesz użyć schematu niestandardowego, takiego jak:
<a href="example-app:showProfile">Show Profile</a>
Następnie możesz obsługiwać ten adres URL w metodzie shouldOverrideUrlLoading()
w ten sposób:
// 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 } }
// 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; }
Interfejs API shouldOverrideUrlLoading()
służy przede wszystkim do uruchamiania intencji w przypadku określonych adresów URL. Podczas jego wdrażania pamiętaj, aby zwracać false
w przypadku adresów URL, których uchwyty to WebView
. Nie musisz jednak ograniczać się do uruchamiania intencji. W powyższych przykładach kodu możesz zastąpić intencje uruchamiania dowolnym zachowaniem niestandardowym.
Poruszanie się po historii stron internetowych
Gdy WebView
zastąpi wczytywanie adresu URL, automatycznie będzie gromadzić historię odwiedzonych stron internetowych. Możesz przechodzić wstecz i do przodu w
historię z goBack()
i
goForward()
Na przykład poniżej pokazujemy, jak urządzenie Activity
może korzystać z Wstecz
przycisk przechodzenia wstecz:
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) }
@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); }
Jeśli używasz AndroidaX AppCompat
1.6.0 lub nowszego, możesz uprościć poprzednią wersję
jeszcze więcej:
onBackPressedDispatcher.addCallback { // Check whether there's history. if (myWebView.canGoBack()) { myWebView.goBack() } }
onBackPressedDispatcher.addCallback { // Check whether there's history. if (myWebView.canGoBack()) { myWebView.goBack(); } }
Metoda canGoBack()
zwraca wartość true, jeśli użytkownik ma historię strony internetowej, którą chce odwiedzić. Podobnie możesz użyć canGoForward()
, aby sprawdzić, czy istnieje historia do przodu. Jeśli nie sprawdzisz tego,
gdy użytkownik dotrze do końca historii, goBack()
i goForward()
robią to
nic.
Obsługa zmian konfiguracji urządzenia
Podczas działania stan aktywności zmienia się, gdy zmienia się konfiguracja urządzenia, np. gdy użytkownik obróci urządzenie lub zamknie edytor metody wprowadzania (IME). Te zmiany powodują zniszczenie aktywności obiektu WebView
i utworzenie nowej aktywności, która tworzy też nowy obiekt WebView
, który wczytuje adres URL usuniętego obiektu. Aby zmienić domyślne zachowanie aktywności, możesz zmienić sposób, w jaki obsługuje ona zmiany orientation
w pliku manifestu. Więcej informacji
na temat obsługi zmian konfiguracji w trakcie działania, przeczytaj artykuł Obsługuj konfigurację
zmian.
Zarządzanie oknami
Domyślnie prośby o otwieranie nowych okien są ignorowane. Dzieje się tak niezależnie od tego, czy są otwierane przez JavaScript czy przez atrybut docelowy w linku. Możesz dostosować
WebChromeClient
, aby dostosować sposób otwierania wielu
oknach.
Aby zwiększyć bezpieczeństwo aplikacji, najlepiej zablokuj wyskakujące okienka i nowe okna,
przed otwarciem. Najbezpieczniejszym sposobem wdrożenia tego sposobu jest przekazanie funkcji "true"
do
setSupportMultipleWindows()
ale nie zastępują
onCreateWindow()
, od której zależy wartość setSupportMultipleWindows()
. Ta logika uniemożliwia
strona, która w linkach korzysta z elementu target="_blank"
.