Membangun aplikasi web di WebView

Menggunakan WebView untuk mengirimkan aplikasi web atau laman web sebagai bagian dari aplikasi klien. Class WebView adalah ekstensi class View Android yang memungkinkan Anda menampilkan halaman web sebagai bagian dari tata letak aktivitas Anda. Contoh ini tidak menyertakan fitur dari {i>browser<i} web yang sepenuhnya dikembangkan, seperti kontrol navigasi atau di kolom URL. Semua yang dilakukan WebView, secara default, menampilkan halaman web.

WebView dapat membantu memberikan informasi di aplikasi Anda yang mungkin perlu pembaruan, seperti perjanjian pengguna akhir atau panduan pengguna. Di dalam aplikasi Android, Anda dapat membuat Activity yang berisi WebView, lalu gunakan untuk menampilkan dokumen Anda yang dihosting secara online.

WebView juga dapat membantu saat aplikasi Anda menyediakan data kepada pengguna yang memerlukan koneksi internet untuk mengambil data, seperti email. Dalam hal ini, Anda mungkin merasa bahwa lebih mudah untuk membuat WebView di aplikasi Android yang menampilkan web dengan semua data pengguna. Daripada membuat permintaan jaringan, menguraikan data dan merendernya dalam tata letak Android. Sebagai gantinya, Anda bisa mendesain laman web yang disesuaikan untuk perangkat berbasis Android, lalu menerapkan WebView di aplikasi Android yang memuat halaman web.

Dokumen ini menjelaskan cara mulai menggunakan WebView, cara mengikat JavaScript dari halaman web Anda ke kode sisi klien di aplikasi Android Anda, cara menangani navigasi halaman, dan cara mengelola jendela saat menggunakan WebView.

Menggunakan WebView pada versi Android sebelumnya

Untuk menggunakan kemampuan WebView yang lebih baru dengan aman di perangkat tempat aplikasi Anda lalu tambahkan kode AndroidX Library Webkit. Ini adalah instance library yang dapat ditambahkan ke aplikasi Anda untuk menggunakan android.webkit API yang tidak yang tersedia untuk versi platform sebelumnya.

Tambahkan ke file build.gradle Anda sebagai berikut:

Kotlin

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

Groovy

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

Jelajahi WebView contoh di GitHub untuk mengetahui detail selengkapnya.

Menambahkan WebView ke aplikasi

Untuk menambahkan WebView ke aplikasi, Anda dapat menyertakan elemen <WebView> di tata letak aktivitas atau tetapkan seluruh jendela Activity sebagai WebView di onCreate().

Menambahkan WebView di tata letak aktivitas

Untuk menambahkan WebView ke aplikasi Anda di tata letak, tambahkan kode berikut ke file XML tata letak aktivitas Anda:

<WebView
    android:id="@+id/webview"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
/>

Untuk memuat halaman web di WebView, gunakan loadUrl(), sebagai yang ditunjukkan dalam contoh berikut:

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

Menambahkan WebView di onCreate()

Untuk menambahkan WebView ke aplikasi Anda dalam metode onCreate() aktivitas, gunakan logika yang mirip dengan berikut ini:

Kotlin

val myWebView = WebView(activityContext)
setContentView(myWebView)

Java

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

Kemudian muat halaman:

Kotlin

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

Java

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

Atau muat URL dari 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");

Aplikasi Anda harus memiliki akses ke internet. Untuk mendapatkan akses internet, minta Izin INTERNET di seperti yang ditunjukkan dalam contoh berikut:

<manifest ... >
    <uses-permission android:name="android.permission.INTERNET" />
    ...
</manifest>

Anda dapat menyesuaikan WebView dengan melakukan salah satu tindakan berikut:

  • Mengaktifkan dukungan layar penuh menggunakan WebChromeClient Kelas ini juga dipanggil saat WebView memerlukan izin untuk mengubah UI aplikasi host, seperti membuat atau menutup jendela atau mengirim dialog JavaScript ke . Untuk mempelajari lebih lanjut proses debug dalam konteks ini, baca Men-debug web aplikasi.
  • Menangani peristiwa yang memengaruhi rendering konten, seperti error pada formulir kiriman atau navigasi menggunakan WebViewClient Anda juga dapat menggunakan subclass ini untuk menangkap pemuatan URL.
  • Mengaktifkan JavaScript dengan mengubah WebSettings
  • Menggunakan JavaScript untuk mengakses objek framework Android yang telah Anda masukkan menjadi WebView.

Menggunakan JavaScript di WebView

Jika halaman web yang ingin dimuat di WebView menggunakan JavaScript, Anda harus mengaktifkan JavaScript untuk WebView Anda. Setelah mengaktifkan JavaScript, Anda dapat membuat antarmuka antara kode aplikasi dan kode JavaScript Anda.

Aktifkan JavaScript

JavaScript dinonaktifkan di WebView secara default. Anda dapat mengaktifkannya melalui WebSettings dilampirkan ke WebView Anda. Ambil WebSettings dengan getSettings(), lalu aktifkan JavaScript dengan setJavaScriptEnabled().

Lihat contoh berikut:

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 memberikan akses ke berbagai setelan lain yang mungkin Anda temukan berguna Misalnya, jika Anda mengembangkan aplikasi web yang dirancang khusus untuk WebView di aplikasi Android, Anda dapat menentukan string agen pengguna dengan setUserAgentString(), lalu buat kueri agen pengguna khusus di halaman web Anda untuk memverifikasi bahwa meminta laman web Anda adalah aplikasi Android Anda.

Mengikat kode JavaScript ke kode Android

Saat mengembangkan aplikasi web yang didesain khusus untuk WebView di aplikasi Android, Anda dapat membuat antarmuka di antara kode JavaScript dan kode Android sisi klien. Misalnya, kode JavaScript Anda bisa memanggil metode di kode Android Anda untuk menampilkan Dialog, alih-alih menggunakan fungsi alert() JavaScript.

Untuk mengikat antarmuka baru antara JavaScript dan kode Android, panggil addJavascriptInterface(), meneruskannya ke instance class untuk mengikat ke JavaScript dan nama antarmuka yang dapat dipanggil JavaScript Anda untuk mengakses class tersebut.

Misalnya, Anda dapat menyertakan class berikut di aplikasi 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();
    }
}

Dalam contoh ini, class WebAppInterface memungkinkan halaman web membuat Pesan Toast, menggunakan showToast() .

Anda dapat mengikat class ini ke JavaScript yang berjalan di WebView dengan addJavascriptInterface(), seperti yang ditunjukkan dalam contoh berikut:

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

Tindakan ini akan membuat antarmuka bernama Android untuk JavaScript yang berjalan di WebView. Pada tahap ini, aplikasi web Anda memiliki akses ke Class WebAppInterface. Misalnya, berikut ini beberapa HTML dan JavaScript yang akan membuat pesan toast menggunakan antarmuka baru saat pengguna mengetuk tombol:

<input type="button" value="Say hello" onClick="showAndroidToast('Hello Android!')" />

<script type="text/javascript">
    function showAndroidToast(toast) {
        Android.showToast(toast);
    }
</script>

Anda tidak perlu melakukan inisialisasi antarmuka Android dari JavaScript. Tujuan WebView otomatis menyediakannya untuk halaman web Anda. Jadi, ketika seorang pengguna mengetuk tombol, fungsi showAndroidToast() akan menggunakan antarmuka Android untuk memanggil metode WebAppInterface.showToast().

Menangani navigasi halaman

Saat pengguna mengetuk link dari halaman web di WebView, secara default, Android meluncurkan aplikasi yang menangani URL. Biasanya, {i>browser<i} web {i>default<i} akan terbuka dan memuat URL tujuan. Namun, Anda bisa mengganti perilaku ini untuk WebView jadi link akan terbuka dalam WebView. Kemudian, Anda dapat membiarkan pengguna menavigasi mundur dan maju melalui riwayat laman web mereka yang dipertahankan oleh WebView Anda.

Untuk membuka link yang diketuk oleh pengguna, berikan WebViewClient untuk WebView Anda menggunakan setWebViewClient() Semua link yang diketuk pengguna akan dimuat di WebView Anda. Jika Anda menginginkan lebih banyak kontrol atas tempat link yang diklik dimuat, buat WebViewClient Anda sendiri yang menggantikan shouldOverrideUrlLoading() . Contoh berikut mengasumsikan bahwa MyWebViewClient adalah class dalam dari 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;
  }
}

Kemudian, buat instance WebViewClient baru ini untuk WebView:

Kotlin

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

Java

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

Sekarang, ketika pengguna mengetuk tautan, sistem akan memanggil metode Metode shouldOverrideUrlLoading(), yang memeriksa apakah host URL cocok domain tertentu, seperti yang didefinisikan dalam contoh sebelumnya. Jika cocok, maka metode ini menampilkan nilai salah dan tidak mengganti pemuatan URL. Fungsi ini memungkinkan WebView memuat URL seperti biasa. Jika {i>host<i} URL tidak sesuai, maka Intent dibuat untuk meluncurkan versi default Activity untuk menangani URL, yang di-resolve ke browser web default pengguna.

Menangani URL kustom

WebView menerapkan pembatasan saat meminta resource dan menyelesaikan link yang menggunakan skema URL kustom. Misalnya, jika Anda menerapkan callback seperti shouldOverrideUrlLoading() atau shouldInterceptRequest(), maka WebView memanggilnya hanya untuk URL yang valid.

Misalnya, WebView mungkin tidak memanggil metode shouldOverrideUrlLoading() Anda untuk link seperti ini:

<a href="showProfile">Show Profile</a>

URL yang tidak valid, seperti yang ditunjukkan pada contoh sebelumnya, sudah ditangani secara tidak konsisten di WebView, jadi sebaiknya gunakan URL dengan format yang benar. Anda dapat menggunakan skema kustom atau URL HTTPS untuk domain yang kontrol.

Alih-alih menggunakan {i>string<i} sederhana di sebuah tautan, seperti dalam contoh sebelumnya, Anda dapat gunakan skema kustom seperti berikut:

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

Anda kemudian dapat menangani URL ini di metode shouldOverrideUrlLoading() seperti ini:

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

shouldOverrideUrlLoading() API terutama ditujukan untuk meluncurkan intent untuk URL tertentu. Saat menerapkannya, pastikan untuk menampilkan false untuk URL tuas WebView. Namun, Anda tidak dibatasi untuk meluncurkan intent. Anda dapat mengganti intent peluncuran dengan perilaku kustom apa pun dalam kode sebelumnya sampel.

Saat WebView mengganti pemuatan URL, URL akan otomatis mengakumulasi riwayat laman web yang dikunjungi. Anda dapat menavigasi mundur dan maju melalui histori dengan goBack() dan goForward().

Misalnya, contoh berikut menunjukkan cara Activity dapat menggunakan tombol Kembali di perangkat untuk menavigasi mundur:

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

Jika aplikasi Anda menggunakan AndroidX AppCompat 1.6.0+, Anda dapat menyederhanakan cuplikan ini lebih banyak lagi:

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

Metode canGoBack() akan menampilkan nilai 'true' (benar) jika ada histori halaman web yang dapat dikunjungi pengguna. Demikian juga, Anda dapat menggunakan canGoForward() untuk memeriksa apakah ada histori penerusan. Jika Anda tidak melakukan pemeriksaan ini, maka setelah pengguna mencapai akhir histori, goBack() dan goForward() akan tidak terjadi apa-apa.

Menangani perubahan konfigurasi perangkat

Selama runtime, perubahan status aktivitas terjadi saat konfigurasi perangkat perubahan, seperti saat pengguna memutar perangkat atau menutup editor metode input (IME). Perubahan ini menyebabkan aktivitas objek WebView dihancurkan dan aktivitas baru dibuat, yang juga membuat objek WebView baru yang dimuat URL objek yang dihancurkan. Untuk mengubah perilaku default aktivitas, Anda dapat ubah caranya menangani perubahan orientation dalam manifes Anda. Untuk mempelajari lebih lanjut tentang menangani perubahan konfigurasi selama runtime, baca Menangani konfigurasi perubahan.

Kelola jendela

Secara default, permintaan untuk membuka jendela baru akan diabaikan. Ini akan tetap terjadi baik ketika mereka dibuka oleh JavaScript atau oleh atribut target dalam link. Anda dapat menyesuaikan WebChromeClient untuk menyediakan perilaku Anda sendiri saat membuka beberapa Windows.

Agar aplikasi Anda lebih aman, sebaiknya cegah pop-up dan jendela baru agar tidak saat membuka. Cara paling aman untuk menerapkan perilaku ini adalah dengan meneruskan "true" ke dalam setSupportMultipleWindows() tetapi tidak mengganti onCreateWindow() , yang diandalkan oleh setSupportMultipleWindows(). Logika ini mencegah halaman yang menggunakan target="_blank" di link-nya agar tidak dimuat.