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

İstemci uygulamasının bir parçası olarak web uygulaması veya web sayfası sunmak için WebView kullanın. WebView sınıfı, Android'in View sınıfının bir uzantısıdır ve web sayfalarını etkinlik düzeninizin bir parçası olarak görüntülemenizi sağlar. Gezinme kontrolleri veya adres çubuğu gibi tam olarak geliştirilmiş bir web tarayıcısının özelliklerini içermez. Varsayılan olarak WebView yalnızca bir web sayfası gösterir.

WebView, uygulamanızda güncellemeniz gerekebilecek bilgileri (ör. son kullanıcı sözleşmesi veya kullanıcı kılavuzu) sağlamanıza yardımcı olabilir. Android uygulamanızda, Activity oluşturup WebView ekleyebilir, ardından bu Activity'ı kullanarak internette barındırılan dokümanınızı gösterebilirsiniz.

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

Bu belgede WebView ile nasıl başlayacağınız, web sayfanızdaki JavaScript'i Android uygulamanızdaki istemci tarafı koduna nasıl bağlayacağınız, sayfa gezinmesini nasıl işleyeceğiniz ve WebView kullanı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 statik bir kitaplıktır.

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

Kotlin

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

Groovy

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

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

Uygulamanıza WebView ekleme

Uygulamanıza WebView eklemek için <WebView> öğesini etkinlik düzeninize ekleyebilir veya onCreate() içinde Activity penceresinin tamamını WebView olarak ayarlayabilirsiniz.

Etkinlik düzenine WebView 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() 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çinde WebView ekleme

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

Kotlin

val myWebView = WebView(activityContext)
setContentView(myWebView)

Java

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

Ardından 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ükleyin:

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ğıdaki yöntemlerden herhangi birini kullanarak WebView simgenizi özelleştirebilirsiniz:

  • WebChromeClient kullanarak tam ekran desteğini etkinleştirme. Bu sınıf, WebView ana makine uygulamasının kullanıcı arayüzünü değiştirmek için izne ihtiyaç duyduğunda da çağrılır. Örneğin, pencere oluşturma veya kapatma ya da kullanıcıya JavaScript iletişim kutuları gönderme gibi durumlarda bu sınıf çağrılır. Bu bağlamda hata ayıklama hakkında daha fazla bilgi edinmek için Web uygulamalarında hata ayıklama başlıklı makaleyi inceleyin.
  • İçerik oluşturmayı etkileyen etkinlikleri işleme (ör. form gönderimlerindeki hatalar veya WebViewClient kullanılarak yapılan gezinme). URL yüklemeyi durdurmak için bu alt sınıfı da kullanabilirsiniz.
  • WebSettings dosyasını değiştirerek JavaScript'i etkinleştirme.
  • WebView öğesine yerleştirdiğiniz Android çerçeve nesnelerine erişmek için JavaScript kullanma.

WebView'da JavaScript kullanma

WebView içinde yüklemek istediğiniz web sayfasında JavaScript kullanılı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

JavaScript, WebView'da varsayılan olarak devre dışıdır. Bu özelliği, WebView cihazınıza bağlı WebSettings üzerinden etkinleştirebilirsiniz. getSettings() ile WebSettings öğesini 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, faydalı bulabileceğiniz çeşitli diğer 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ızı isteyen istemcinin Android uygulamanız olduğunu doğrulamak için web sayfanızdaki özel kullanıcı aracısını sorgulayabilirsiniz.

JavaScript kodunu Android koduna bağlama

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

JavaScript ve Android kodunuz arasında yeni bir arayüz bağlamak için addJavascriptInterface() işlevini çağırın. Bu işlev, JavaScript'inize bağlanacak bir sınıf örneği ve JavaScript'inizin sınıfa erişmek için çağırabileceği bir arayüz adı iletilmelidir.

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

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ı, showToast() yöntemini kullanarak web sayfasının Toast mesajı oluşturmasına olanak tanır.

Bu sınıfı, aşağıdaki örnekte gösterildiği gibi WebView ile addJavascriptInterface() içinde ç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 işlem, 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 bildirim mesajı oluşturan bazı HTML ve JavaScript kodları aşağıda verilmiştir:

<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ız gerekmez. WebView, otomatik olarak web sayfanızda kullanılabilir hale getirir. Bu nedenle, 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 yönetme

Kullanıcı, WebView uygulamanızdaki bir web sayfasında bağlantıya dokunduğunda Android, varsayılan olarak 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. Ancak, bağlantıların WebView içinde açılması için WebView cihazınızda bu davranışı geçersiz kılabilirsiniz. Ardından, kullanıcının WebView tarafından tutulan web sayfası geçmişinde ileri ve geri gitmesine izin verebilirsiniz.

Kullanıcının dokunduğu bağlantıları açmak için WebViewClient WebView kullanarak setWebViewClient(). Kullanıcının dokunduğu tüm bağlantılar WebView'nizde yüklenir. Tıklanan bir bağlantının yüklendiği yer üzerinde daha fazla kontrol sahibi olmak istiyorsanız WebViewClient yöntemini geçersiz kılan kendi shouldOverrideUrlLoading() yöntemini oluşturun. Aşağıdaki örnekte, MyWebViewClient öğesinin Activity öğesinin iç sınıfı olduğu varsayılmaktadı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());

Kullanıcı bir bağlantıya dokunduğunda sistem, shouldOverrideUrlLoading() yöntemini çağırır. Bu yöntem, URL ana makinesinin önceki örnekte tanımlandığı gibi belirli bir alanla eşleşip eşleşmediğini kontrol eder. Eşleşirse yöntem false değerini döndürür ve URL yüklemesini geçersiz kılmaz. Bu ayar, WebView eklentisinin URL'yi normal şekilde yüklemesine olanak tanır. URL ana makinesi eşleşmezse URL'leri işlemek için varsayılan Activity'ı başlatmak üzere bir Intent oluşturulur. Bu, kullanıcının varsayılan web tarayıcısına yönlendirilir.

Herkese açık kullanıcı adı özel URL'leri

WebView, kaynak istenirken ve özel URL şeması kullanan bağlantılar çözümlenirken 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österilene benzer 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 bağlantıda basit bir dize kullanmak yerine aşağıdaki gibi özel bir şema kullanabilirsiniz:

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

Ardından, 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, öncelikle belirli URL'ler için amaç başlatmak üzere tasarlanmıştır. Bu API'yi uygularken WebView tarafından işlenen URL'ler için false döndürdüğünüzden emin olun. Ancak yalnızca amaç başlatmakla sınırlı değilsiniz. Başlatma amaçlarını, önceki kod örneklerindeki herhangi bir özel davranışla değiştirebilirsiniz.

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

Örneğin, aşağıdaki resimde Activity karakterinin, cihazın geri düğmesini kullanarak nasıl geriye gidebileceğ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ız AndroidX AppCompat 1.6.0+ kullanı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();
    }
}

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

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

Çalışma zamanında, cihazın yapılandırması değiştiğinde (ör. kullanıcılar cihazı döndürdüğünde veya bir giriş yöntemi düzenleyicisini (IME) kapattığında) etkinlik durumu değişiklikleri meydana gelir. Bu değişiklikler, WebView nesnesinin etkinliğinin yok edilmesine ve yeni bir etkinliğin oluşturulmasına neden olur. Bu da yok edilen nesnenin URL'sini yükleyen yeni bir WebView nesnesi oluşturur. Etkinliğinizin varsayılan davranışını değiştirmek için manifest dosyanızdaki orientation değişiklikleri nasıl işlediğini değiştirebilirsiniz. Çalışma zamanında yapılandırma değişikliklerini işleme hakkında daha fazla bilgi edinmek için Yapılandırma değişikliklerini işleme başlıklı makaleyi inceleyin.

Pencereleri yönetme

Varsayılan olarak, yeni pencereleri açma istekleri yoksayılır. Bu durum, pencerelerin JavaScript ile veya bir bağlantıdaki hedef özelliğiyle açılması fark etmeksizin geçerlidir. Birden çok pencere açma davranışını kendinize göre ayarlamak için WebChromeClient cihazınızı özelleştirebilirsiniz.

Uygulamanızın güvenliğini artırmak için pop-up'ların ve yeni pencerelerin açılmasını engellemeniz önerilir. Bu davranışı uygulamanın en güvenli yolu, "true" değerini setSupportMultipleWindows() içine iletmektir ancak setSupportMultipleWindows() değerinin bağlı olduğu onCreateWindow() yöntemini geçersiz kılmamaktır. Bu mantık, bağlantılarında target="_blank" kullanılan sayfaların yüklenmesini engeller.