Tworzenie aplikacji internetowych w komponencie WebView

Użyj WebView do dostarczania aplikacji internetowej lub stronę internetową jako część aplikacji klienckiej. Klasa WebView to jest to rozszerzenie klasy View Androida, które pozwala wyświetlasz strony internetowe jako element 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 pokazuje 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 możesz okaże się, że łatwiej jest utworzyć WebView w aplikacji na Androida, która wyświetla ze wszystkimi danymi użytkownika zamiast wysyłania żądania sieciowego, analizowanie danych i renderowanie ich w układzie Androida. Zamiast tego możesz zaprojektować strony dostosowanej do urządzeń z systemem Android, a następnie zaimplementować WebView w aplikacji na Androida, która wczytuje stronę internetową.

Ten dokument opisuje, jak zacząć korzystać z usługi WebView i jak je powiązać JavaScript ze strony internetowej do kodu po stronie klienta w aplikacji na Androida. obsługi nawigacji na stronach i zarządzania 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 element statyczny biblioteka, którą możesz dodać do swojej aplikacji, aby używać interfejsów API android.webkit, które nie są we wcześniejszych wersjach platformy.

Dodaj go do pliku build.gradle w ten sposób:

Kotlin

dependencies {
    implementation("androidx.webkit:webkit:1.8.0")
}

Odlotowe

dependencies {
    implementation ("androidx.webkit:webkit:1.8.0")
}

Poznaj WebView przykład znajdziesz na GitHubie.

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 WebView, użyj loadUrl(), jako w tym przykładzie:

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");

Dodaj komponent WebView w onCreate()

Aby zamiast tego dodać WebView do aplikacji w metodzie onCreate() aktywności, użyj w podobny sposób:

Kotlin

val myWebView = WebView(activityContext)
setContentView(myWebView)

Java

WebView myWebView = new WebView(activityContext);
setContentView(myWebView);

Następnie wczytaj stronę:

Kotlin

myWebView.loadUrl("http://www.example.com")

Java

myWebView.loadUrl("https://www.example.com");

Możesz też wczytać adres URL z ciągu 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");

Aplikacja musi mieć dostęp do internetu. Aby uzyskać dostęp do internetu, poproś INTERNET na manifestu zgodnie z poniższym przykładem:

<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ługa WebView 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
  • Uzyskiwanie dostępu do wstawionych przez Ciebie obiektów platformy Androida za pomocą JavaScriptu w: 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 JavaScriptu możesz do tworzenia interfejsów między kodem aplikacji a kodem JavaScript.

Włącz obsługę języka JavaScript

W WebView domyślnie JavaScript jest wyłączony. Aby ją włączyć, użyj Urządzenie WebSettings zostało podłączone do urządzenia WebView. Odzyskaj WebSettings za pomocą getSettings(), a następnie włącz JavaScript z setJavaScriptEnabled()

Zobacz ten przykład:

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);

WebSettings umożliwia dostęp do wielu innych ustawień, które możesz znaleźć przydatne. 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.

Powiąż kod 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. Na przykład kod JavaScript może wywoływać metodę w argumencie kod na Androida, by wyświetlić Dialog, zamiast korzystania z funkcji alert() w języku JavaScript.

Aby powiązać nowy interfejs między kodem JavaScript a kodem Androida, użyj wywołania addJavascriptInterface() przekazanie jej instancji klasy w celu powiązania ze skryptem JavaScript i nazwą interfejsu, który JavaScript może wywołać, aby uzyskać dostęp do klasy.

Możesz na przykład umieścić w swojej aplikacji na Androida tę klasę:

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();
    }
}

W tym przykładzie klasa WebAppInterface pozwala stronie internetowej utworzyć Toast wiadomość przy użyciu showToast() .

Możesz powiązać tę klasę z JavaScriptem, który działa w WebView za pomocą addJavascriptInterface() zgodnie z poniższym przykładem:

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");

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 toast za pomocą nowego interfejsu, 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 trzeba inicjować interfejsu Android za pomocą JavaScriptu. 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 zmienić to działanie w przypadku WebView, więc linki otwierają się w aplikacji WebView. Następnie możesz pozwolić użytkownikowi na poruszać się wstecz i do przodu po historii stron internetowych, przez WebView.

Aby otwierać linki kliknięte przez użytkownika, podaj WebViewClient dla: WebView za pomocą setWebViewClient(). Wszystkie linki, które klika użytkownik, wczytują się na urządzeniu 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 założono, że MyWebViewClient jest klasą wewnętrzną z 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;
  }
}

Następnie utwórz instancję nowego WebViewClient dla środowiska WebView:

Kotlin

val myWebView: WebView = findViewById(R.id.webview)
myWebView.webViewClient = MyWebViewClient()

Java

WebView myWebView = (WebView) findViewById(R.id.webview);
myWebView.setWebViewClient(new MyWebViewClient());

Teraz, gdy użytkownik klika link, system wywołuje metodę Metoda shouldOverrideUrlLoading(), która sprawdza, czy host adresu URL pasuje określoną domenę (zgodnie z definicją podaną w poprzednim przykładzie). Jeśli dane będą zgodne, metoda zwraca wartość „false” (fałsz) i nie zastępuje wczytywania adresu URL. Dzięki niemu WebView wczytuje URL w zwykły sposób. Jeśli host adresu URL nie jest zgodny, Utworzono grupę Intent, aby uruchomić aplikację domyślną Activity w przypadku obsługi adresów URL, które otwierają domyślną przeglądarkę użytkownika.

Obsługa niestandardowych adresów URL

WebView stosuje ograniczenia podczas wysyłania próśb o zasoby i rozwiązywania linków używający 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 WebView może nie wywoływać metody shouldOverrideUrlLoading() dla linków podobnych do tego:

<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 używać prostego ciągu w linku, jak w poprzednim przykładzie, możesz użyj niestandardowego schematu, takiego jak:

<a href="example-app:showProfile">Show Profile</a>

Teraz możesz obsługiwać ten URL w metodzie shouldOverrideUrlLoading() jak na przykład to:

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;
}

Interfejs API shouldOverrideUrlLoading() służy przede wszystkim do uruchamiania intencji dla konkretnych adresów URL. Pamiętaj, by podczas implementacji zwrócić wartość false dla adresów URL uchwyty WebView. Nie musisz jednak ograniczać się do wprowadzania intencji. Dostępne opcje zastąp intencje uruchamiania dowolnymi zachowaniami niestandardowymi w poprzednim kodzie przykłady.

Gdy WebView zastąpi wczytanie adresu URL, automatycznie gromadzi dane 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:

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);
}

Jeśli używasz AndroidaX AppCompat 1.6.0 lub nowszego, możesz uprościć poprzednią wersję jeszcze więcej:

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();
    }
}

Metoda canGoBack() zwraca wartość true, jeśli użytkownik ma historię strony internetowej, którą chce odwiedzić. Podobnie Ty może użyć canGoForward() do sprawdzić, czy jest historia przekazywania dalej. Jeśli nie sprawdzisz tego, gdy użytkownik dotrze do końca historii, goBack() i goForward() robią to nic.

Obsługa zmian w konfiguracji urządzenia

W czasie działania stan aktywności zmienia się, gdy konfiguracja urządzenia jest włączona zmian, na przykład gdy użytkownik obróci urządzenie lub zamknie edytor metody wprowadzania. (IME). Te zmiany powodują zniszczenie aktywności obiektu WebView i nową aktywność do utworzenia, co powoduje również utworzenie nowego obiektu WebView, który wczytuje się do adresu URL zniszczonego obiektu. Aby zmienić domyślne zachowanie aktywności, możesz: zmień sposób obsługi zmian typu orientation w pliku manifestu. Aby dowiedzieć się więcej, na temat obsługi zmian konfiguracji w trakcie działania, przeczytaj artykuł Obsługuj konfigurację zmian.

Zarządzaj oknami

Domyślnie żądania otwarcia nowych okien są ignorowane. Nie ma znaczenia, czy są otwierane przez JavaScript lub 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".