Web Görünümü'nde web uygulamaları oluşturma

İstemci uygulamasının parçası olarak bir web uygulaması veya web sayfası göndermek için WebView kullanın. WebView sınıfı, Android View sınıfının bir uzantısıdır. Bu sayede web sayfalarını etkinlik düzeninizin bir parçası olarak görüntüleyebilirsiniz. Tam olarak geliştirilmiş bir web tarayıcısının gezinme denetimleri veya adres çubuğu gibi özelliklerini içermez. WebView uygulamasının yaptığı her şey varsayılan olarak bir web sayfası gösterir.

WebView, uygulamanızda güncellemeniz gerekebilecek bilgileri (ör. son kullanıcı sözleşmesi veya kullanıcı rehberi) sağlamanıza yardımcı olabilir. Android uygulamanızda, WebView içeren bir Activity oluşturabilir ve ardından bu öğeyi kullanarak internette barındırılan dokümanınızı görüntüleyebilirsiniz.

Uygulamanız, e-posta gibi verileri almak için internet bağlantısı gerektiren kullanıcıya veri sağladığında da WebView yardımcı olabilir. Bu durumda, ağ isteği gerçekleştirdikten sonra verileri ayrıştırıp Android düzeninde oluşturmak yerine, Android uygulamanızda tüm kullanıcı verilerini içeren bir web sayfasını gösteren bir WebView oluşturmanın daha kolay olduğunu görebilirsiniz. Bunun yerine, Android destekli cihazlar için uyarlanmış bir web sayfası tasarlayabilir ve ardından Android uygulamanızda web sayfasını yükleyen bir WebView uygulayabilirsiniz.

Bu dokümanda, WebView kullanmaya nasıl başlayacağınız, web sayfanızdan JavaScript'i Android uygulamanızda istemci taraflı koda nasıl bağlayacağınız, sayfada gezinmenin nasıl yapılacağı ve WebView kullanılırken pencereleri nasıl yöneteceğiniz açıklanmaktadır.

Android'in önceki sürümlerinde WebView ile çalışma

Uygulamanızın çalıştığı cihazda daha yeni WebView özelliklerini güvenli bir şekilde kullanmak için AndroidX Webkit kitaplığını ekleyin. Bu, önceki platform sürümlerinde kullanılamayan android.webkit API'lerini kullanmak için uygulamanıza ekleyebileceğiniz bir statik kitaplıktır.

Kodu build.gradle dosyanıza aşağıdaki şekilde ekleyin:

Kotlin

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

Eski

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

Daha fazla bilgi için GitHub'daki WebView örneğini inceleyin.

Uygulamanıza WebView ekleyin

Uygulamanıza WebView eklemek için <WebView> öğesini etkinlik düzeninize ekleyebilir veya onCreate()'te tüm Activity penceresini WebView olarak ayarlayabilirsiniz.

Etkinlik düzeninde Web Görünümü ekleme

Düzende uygulamanıza WebView eklemek için etkinliğinizin düzen XML dosyasına aşağıdaki kodu ekleyin:

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

WebView içinde bir web sayfası yüklemek için aşağıdaki örnekte gösterildiği gibi loadUrl() işlevini kullanın:

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

onCreate() işlevinde bir WebView ekleme

Bunun yerine bir etkinliğin onCreate() yönteminde uygulamanıza WebView eklemek için aşağıdakine benzer bir mantık kullanın:

Kotlin

val myWebView = WebView(activityContext)
setContentView(myWebView)

Java

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

Daha sonra sayfayı yükleyin:

Kotlin

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

Java

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

Alternatif olarak, URL'yi bir HTML dizesinden yükleyebilirsiniz:

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

Uygulamanızın internete erişimi olmalıdır. İnternet erişimi elde etmek için aşağıdaki örnekte gösterildiği gibi manifest dosyanızda INTERNET iznini isteyin:

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

Aşağıdakilerin birini yaparak WebView cihazınızı özelleştirebilirsiniz:

  • WebChromeClient kullanarak tam ekran desteğini etkinleştirme. Bu sınıf, bir WebView ana makine uygulamasının kullanıcı arayüzünü değiştirmek (örneğin pencere oluşturma veya kapatma ya da kullanıcıya JavaScript iletişim kutuları gönderme) için izne ihtiyaç duyduğunda da çağrılır. Bu bağlamda hata ayıklama hakkında daha fazla bilgi edinmek için Web uygulamalarında hata ayıklama bölümüne bakın.
  • Form gönderme veya gezinme hataları gibi içerik oluşturmayı etkileyen etkinlikleri WebViewClient kullanarak işleme. Bu alt sınıfı, URL yüklemeye müdahale etmek için de kullanabilirsiniz.
  • WebSettings değiştirerek JavaScript'i etkinleştirme.
  • WebView öğesine eklediğiniz Android çerçevesi nesnelerine erişmek için JavaScript kullanma.

WebView'da JavaScript kullanma

WebView içinde yüklemek istediğiniz web sayfası JavaScript kullanıyorsa WebView için JavaScript'i etkinleştirmeniz gerekir. JavaScript'i etkinleştirdikten sonra, uygulama kodunuz ile JavaScript kodunuz arasında arayüzler oluşturabilirsiniz.

JavaScript'i etkinleştirme

WebView içinde JavaScript varsayılan olarak devre dışıdır. WebView cihazınıza ekli WebSettings ile bu özelliği etkinleştirebilirsiniz. WebSettings öğesini getSettings() ile alın, ardından setJavaScriptEnabled() ile JavaScript'i etkinleştirin.

Aşağıdaki örneğe bakın:

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, işinize yarayabilecek çok çeşitli ayarlara erişim sağlar. Örneğin, Android uygulamanızdaki WebView için özel olarak tasarlanmış bir web uygulaması geliştiriyorsanız setUserAgentString() ile özel bir kullanıcı aracısı dizesi tanımlayabilir, ardından web sayfanızda özel kullanıcı aracısını sorgulayarak web sayfanızı isteyen istemcinin Android uygulamanız olduğunu doğrulayabilirsiniz.

JavaScript kodunu Android koduna bağlama

Android uygulamanızdaki WebView için özel olarak tasarlanmış bir web uygulaması geliştirirken, JavaScript kodunuz ile istemci taraflı Android kodunuz arasında arayüzler oluşturabilirsiniz. Örneğin, JavaScript kodunuz, JavaScript'in alert() işlevini kullanmak yerine, Dialog görüntülemek için Android kodunuzdaki bir yöntemi çağırabilir.

JavaScript ve Android kodunuz arasında yeni bir arayüz bağlamak için addJavascriptInterface() yöntemini çağırarak JavaScript'inize bağlanması için bir sınıf örneği ve JavaScript'inizin sınıfa erişmek için çağırabileceği bir arayüz adı iletin.

Örneğin, Android uygulamanıza aşağıdaki sınıfı dahil edebilirsiniz:

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

Bu örnekte WebAppInterface sınıfı, web sayfasının showToast() yöntemini kullanarak Toast mesajı oluşturmasını sağlar.

Bu sınıfı, aşağıdaki örnekte gösterildiği gibi WebView içinde addJavascriptInterface() ile çalışan JavaScript'e bağlayabilirsiniz:

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

Bu, WebView içinde çalışan JavaScript için Android adlı bir arayüz oluşturur. Bu noktada, web uygulamanız WebAppInterface sınıfına erişebilir. Örneğin, kullanıcı bir düğmeye dokunduğunda yeni arayüzü kullanarak bir durum mesajı oluşturan HTML ve JavaScript'in bir kısmını burada görebilirsiniz:

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

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

Android arayüzünü JavaScript'ten başlatmanıza gerek yoktur. WebView, bu içeriği otomatik olarak web sayfanızda kullanılabilir hale getirir. Dolayısıyla, bir kullanıcı düğmeye dokunduğunda showAndroidToast() işlevi, WebAppInterface.showToast() yöntemini çağırmak için Android arayüzünü kullanır.

Sayfada gezinmeyi işleme

Kullanıcı, WebView uygulamanızdaki bir web sayfasındaki bağlantıya dokunduğunda varsayılan olarak Android, URL'leri işleyen bir uygulamayı başlatır. Genellikle varsayılan web tarayıcısı açılır ve hedef URL'yi yükler. Bununla birlikte, bağlantıların WebView içinde açılması için WebView için bu davranışı geçersiz kılabilirsiniz. Böylece kullanıcının, WebView tarafından korunan web sayfası geçmişinde geri ve ileri gitmesine izin verebilirsiniz.

Kullanıcının dokunduğu bağlantıları açmak üzere setWebViewClient() kullanarak WebView için bir WebViewClient sağlayın. Kullanıcının dokunduğu tüm bağlantılar WebView içinde yüklenir. Tıklanan bir bağlantının nereye yüklendiği üzerinde daha fazla kontrol sahibi olmak istiyorsanız shouldOverrideUrlLoading() yöntemini geçersiz kılan kendi WebViewClient öğenizi oluşturun. Aşağıdaki örnekte MyWebViewClient değerinin Activity öğesinin bir iç sınıfı olduğu varsayılmıştır.

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

Ardından WebView için bu yeni WebViewClient öğesinin bir örneğini oluşturun:

Kotlin

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

Java

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

Artık kullanıcı bir bağlantıya dokunduğunda sistem, shouldOverrideUrlLoading() yöntemini çağırır. Bu yöntem, URL ana makinesinin belirli bir alan adıyla eşleşip eşleşmediğini kontrol eder. Eşleşirse yöntem false (yanlış) değerini döndürür ve URL yüklemesini geçersiz kılmaz. WebView ürününün URL'yi her zamanki gibi yüklemesini sağlar. URL ana makinesi eşleşmezse URL'lerin işlenmesi için varsayılan Activity öğesini başlatmak üzere bir Intent oluşturulur. Bu varsayılan tarayıcı, kullanıcının varsayılan web tarayıcısına çözümlenir.

Özel URL'leri işleme

WebView, özel URL şeması kullanan kaynakları isterken ve bağlantıları çözümlerken kısıtlamalar uygular. Örneğin, shouldOverrideUrlLoading() veya shouldInterceptRequest() gibi geri çağırmalar uygularsanız WebView bunları yalnızca geçerli URL'ler için çağırır.

Örneğin, WebView, aşağıdaki gibi bağlantılar için shouldOverrideUrlLoading() yönteminizi çağırmayabilir:

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

Önceki örnekte gösterilen gibi geçersiz URL'ler, WebView içinde tutarsız bir şekilde işlenir. Bu nedenle, bunun yerine iyi biçimlendirilmiş bir URL kullanmanızı öneririz. Kuruluşunuzun kontrol ettiği bir alan için özel şema veya HTTPS URL'si kullanabilirsiniz.

Önceki örnekte olduğu gibi, bir bağlantıda basit bir dize kullanmak yerine aşağıdaki gibi özel bir şema kullanabilirsiniz:

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

Daha sonra, bu URL'yi shouldOverrideUrlLoading() yönteminizde şu şekilde işleyebilirsiniz:

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, temel olarak belirli URL'lerde amaçları başlatmak için tasarlanmıştır. API'yi uygularken WebView tarafından işlenen URL'ler için false değerini döndürdüğünüzden emin olun. Ancak niyeti başlatmakla sınırlı değilsiniz. Başlatma amaçlarının yerine önceki kod örneklerindeki herhangi bir özel davranışı kullanabilirsiniz.

WebView, URL yüklemeyi geçersiz kıldığında, ziyaret edilen web sayfalarının geçmişini otomatik olarak toplar. goBack() ve goForward() ile geçmişte geri ve ileri gidebilirsiniz.

Örneğin, aşağıda Activity cihazınızın geri gitmek için cihazın Geri düğmesini nasıl kullanabileceği gösterilmektedir:

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

Uygulamanızda AndroidX AppCompat 1.6.0 veya sonraki bir sürüm kullanılıyorsa önceki snippet'i daha da basitleştirebilirsiniz:

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

Kullanıcının ziyaret edebileceği web sayfası geçmişi varsa canGoBack() yöntemi true değerini döndürür. Benzer şekilde, yönlendirme geçmişi olup olmadığını kontrol etmek için canGoForward() aracını kullanabilirsiniz. Bu kontrolü yapmazsanız kullanıcı geçmişin sonuna ulaştığında goBack() ve goForward() hiçbir şey yapmaz.

Cihaz yapılandırma değişikliklerini işleme

Çalışma zamanı sırasında cihaz yapılandırması değiştiğinde (ör. kullanıcıların cihazı döndürdüğünde veya giriş yöntemi düzenleyiciyi (IME) kapattığında) etkinlik durumu değişiklikleri meydana gelir. Bu değişiklikler, WebView nesnesinin etkinliğinin kaldırılmasına ve yeni bir etkinliğin oluşturulmasına neden olur. Bu da, kaldırılan nesnenin URL'sini yükleyen yeni bir WebView nesnesi oluşturur. Etkinliğinizin varsayılan davranışını değiştirmek için manifest dosyanızda orientation değişikliklerini işleme şeklini değiştirebilirsiniz. Çalışma zamanı sırasında yapılandırma değişikliklerini ele alma hakkında daha fazla bilgi edinmek için Yapılandırma değişikliklerini işleme bölümünü okuyun.

Pencereleri yönetme

Varsayılan olarak, yeni pencereler açma istekleri yoksayılır. Bu durum, ister JavaScript tarafından ister bir bağlantıdaki hedef özellik tarafından açılmış olsun geçerlidir. Birden fazla pencere açarken kendi çalışma şeklinizi sağlayacak şekilde WebChromeClient öğenizi özelleştirebilirsiniz.

Uygulamanızın daha güvenli olmasını sağlamak için en iyisi pop-up'ların ve yeni pencerelerin açılmasını engellemektir. Bu davranışı uygulamanın en güvenli yolu, "true" öğesini setSupportMultipleWindows() öğesine iletmek ancak setSupportMultipleWindows() tarafından kullanılan onCreateWindow() yöntemini geçersiz kılmamaktır. Bu mantık, bağlantılarında target="_blank" kullanan sayfaların yüklenmesini engeller.