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

Bir web uygulamasını veya web sayfasını istemci uygulamasının parçası olarak yayınlamak için WebView aracını kullanın. WebView sınıfı, Android'in 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 gelişmiş bir web tarayıcısının özellikleri (ör. gezinme kontrolleri veya adres çubuğu) bu tarayıcıda bulunmaz. WebView, varsayılan olarak bir web sayfası gösterir.

WebView, uygulamanızda son kullanıcı sözleşmesi veya kullanıcı kılavuzu gibi güncellemeniz gerekebilecek bilgileri sağlamanıza yardımcı olabilir. Android uygulamanızda, WebView içeren bir Activity oluşturabilir ve ardından bu WebView'ı kullanarak internette barındırılan belgenizi görüntüleyebilirsiniz.

WebView, uygulamanız kullanıcıya e-posta gibi verileri almak için internet bağlantısı gerektiren veriler sağladığında da yardımcı olabilir. Bu durumda, bir ağ isteği gerçekleştirip 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 cihazlara özel bir web sayfası tasarlayabilir ve ardından Android uygulamanıza web sayfasını yükleyen bir WebView uygulayabilirsiniz.

Bu belgede, WebView'ü kullanmaya başlama, web sayfanızdaki JavaScript'i Android uygulamanızdaki istemci tarafı koda bağlama, sayfa gezinmesini yönetme ve WebView'ü kullanırken pencereleri yönetme hakkında bilgiler verilmektedir.

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.

Kodu build.gradle dosyanıza aşağıdaki şekilde 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ğini inceleyin.

Uygulamanıza WebView ekleme

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

Etkinlik düzenine 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çine bir web sayfası yüklemek için aşağıdaki örnekte gösterildiği gibi loadUrl() öğesini 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);

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ü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>

WebView'nizi aşağıdakilerden birini yaparak özelleştirebilirsiniz:

  • WebChromeClient kullanarak tam ekran desteğini etkinleştirme. Bu sınıf, WebView'ün ana uygulamanın kullanıcı arayüzünü değiştirmek için izne ihtiyacı olduğunda (ör. pencere oluşturma veya kapatma ya da kullanıcıya JavaScript iletişim kutuları gönderme) 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 dosyasını değiştirerek JavaScript'i etkinleştirme
  • Bir WebView içine yerleştirdiğiniz Android çerçeve nesnelerine erişmek için JavaScript kullanmak.

Web Görünümü'nde 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

JavaScript, WebView'te varsayılan olarak devre dışıdır. Bu özelliği, WebView cihazınıza bağlı WebSettings üzerinden etkinleştirebilirsiniz. getSettings() ile WebSettings'ü 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 tarafı Android kodu 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'iniz ile Android kodunuz arasında yeni bir arayüz bağlamak için addJavascriptInterface()'i çağırın. Bu çağrıda, 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ı gönderin.

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

Aşağıdaki örnekte gösterildiği gibi, bu sınıfı addJavascriptInterface() ile WebView'ünüzde ç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 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'den başlatmanıza gerek yoktur. WebView, bu verileri web sayfanızda otomatik olarak 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'ünüzdeki bir web sayfasındaki bağlantıya dokunduğunda Android varsayılan olarak URL'leri işleyen bir uygulama başlatır. Genellikle varsayılan web tarayıcısı açılır ve hedef URL yüklenir. Ancak bağlantıların WebView'inizde açılması için WebView'iniz için bu davranışı geçersiz kılabilirsiniz. Ardından 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 için setWebViewClient() kullanarak WebView için bir WebViewClient sağlayın. Kullanıcının dokunduğu tüm bağlantılar WebView'ünüze yüklenir. Tıklanan bir bağlantının nerede yükleneceği üzerinde daha fazla kontrol sahibi olmak istiyorsanız shouldOverrideUrlLoading() yöntemini geçersiz kılan kendi WebViewClient yönteminizi oluşturun. Aşağıdaki örnekte, MyWebViewClient'nin Activity sınıfının 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());

Artık kullanıcı bir bağlantıya dokunduğunda sistem, URL ana makinesinin önceki örnekte tanımlandığı gibi belirli bir alanla eşleşip eşleşmediğini kontrol eden shouldOverrideUrlLoading() yöntemini çağırır. Eşleşirse yöntem yanlış değerini döndürür ve URL yüklemeyi geçersiz kılmaz. WebView'ün URL'yi her zamanki gibi 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 Activity, kullanıcının varsayılan web tarayıcısına yönlendirir.

Özel URL'leri kullanma

WebView, özel URL şeması kullanan kaynakları isteyip çözerken kısıtlamalar uygular. Örneğin, shouldOverrideUrlLoading() veya shouldInterceptRequest() gibi geri çağırma işlevleri 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'te tutarlı bir şekilde işlenmez. 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>

Ardından bu URL'yi shouldOverrideUrlLoading() yönteminizde aşağıdaki gibi 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 intent'ler başlatmak amacıyla tasarlanmıştır. API'yi uygularken, WebView tarafından yönetilen URL'ler için false döndürdüğünüzden emin olun. Ancak niyeti başlatmayla 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ğıdaki resimde Activity'ün geriye 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ız AndroidX AppCompat 1.6.0 ve sonraki sürümleri 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 doğru değerini döndürür. Benzer şekilde, ileri geçmiş olup olmadığını kontrol etmek için canGoForward() simgesini kullanabilirsiniz. Bu kontrolü yapmazsanız kullanıcı geçmişin sonuna ulaştığında goBack() ve goForward() hiçbir şey yapmaz.

Cihaz yapılandırması 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ürmesi veya bir giriş yöntemi düzenleyicisini (IME) kapatması) 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 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 pencere açma istekleri yoksayılır. Bu durum, JavaScript tarafından mı yoksa bağlantıdaki hedef özelliği tarafından mı açıldıklarına bakılmaksızın 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ı için pop-up'ların ve yeni pencerelerin açılmasını engellemeniz önerilir. Bu davranışı uygulamanın en güvenli yolu, "true" öğesini setSupportMultipleWindows() yöntemine iletmek ancak setSupportMultipleWindows() öğesinin bağlı olduğu onCreateWindow() yöntemini geçersiz kılmamaktır. Bu mantık, bağlantılarında target="_blank" kullanan sayfaların yüklenmesini engeller.