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

Bir web uygulamasını veya web sayfasını istemci uygulamasının bir parçası olarak sunmak için WebView sınıfını 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ülemenize olanak tanır. Gezinme kontrolleri veya adres çubuğu gibi tam gelişmiş bir web tarayıcısının özelliklerini içermez. WebView, varsayılan olarak yalnızca 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 bunu internette barındırılan dokümanınızı görüntülemek için kullanabilirsiniz.

WebView, uygulamanızın kullanıcıya veri almak için internet bağlantısı gerektiren veriler (ör. e-posta) sağladığı durumlarda da yardımcı olabilir. Bu durumda, ağ isteği gönderip verileri ayrıştırmak ve Android düzeninde oluşturmak yerine Android uygulamanızda tüm kullanıcı verilerini içeren bir web sayfası gösteren 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 ardından Android uygulamanızda web sayfasını yükleyen bir WebView uygulayabilirsiniz.

Bu belgede, WebView kullanmaya nasıl başlayacağınız, web sayfanızdaki JavaScript'i Android uygulamanızdaki istemci tarafı koduna nasıl bağlayacağınız, sayfada gezinmeyi nasıl yöneteceğ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 Jetpack 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.

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

Kotlin

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

Modern

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 etkinlik düzeninize <WebView> öğesini ekleyebilir veya onCreate içinde tüm Activity penceresini 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() yöntemine 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 internet 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 cihazınızı aşağıdaki yöntemlerden birini kullanarak ö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 için izin istediğinde de çağrılır. Örneğin, pencere oluşturma veya kapatma ya da kullanıcıya JavaScript iletişim kutuları gönderme. Bu bağlamda hata ayıklama hakkında daha fazla bilgi edinmek için Web uygulamalarında hata ayıklama başlıklı makaleyi okuyun.
  • Form gönderimlerindeki hatalar veya WebViewClient kullanarak gezinme gibi içerik oluşturmayı etkileyen etkinlikleri işleme. URL yüklemeyi engellemek için de bu alt sınıfı 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 kullanma.

WebView'da JavaScript kullanma

WebView uygulamanızda yüklemek istediğiniz web sayfası JavaScript kullanıyorsa WebView uygulamanız 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ştir

JavaScript, WebView içinde varsayılan olarak devre dışıdır. WebView hesabınıza bağlı WebSettings üzerinden 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, faydalı bulabileceğiniz ç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ızı isteyen istemcinin Android uygulamanız olduğunu doğrulamak için web sayfanızda özel kullanıcı aracısını sorgulayabilirsiniz.

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östermek 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ğırın. Bu yönteme, 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ı iletin.

Daha modern ve güvenli API'ler de dahil olmak üzere JavaScript ile yerel kod arasında iletişim kurma hakkında daha fazla bilgi edinmek için JSBridge ile yerel API'lere erişme başlıklı makaleyi inceleyin.

Ö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, addJavascriptInterface() ile WebView uygulamanızda çalışan JavaScript'e bu sınıfı 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 kısa süreli mesaj oluşturan 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>

JavaScript'ten Android arayüzünü başlatmanız gerekmez. WebView, bu verileri web sayfanızda otomatik olarak kullanılabilir hale getirir. Böylece 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 bulunan 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'yi yükler. Ancak bu davranışı WebView için geçersiz kılarak bağlantıların WebView içinde açılmasını sağlayabilirsiniz. Ardından, kullanıcının WebView tarafından tutulan 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 uygulamanızda yüklenir. Tıklanan bir bağlantının nerede yükleneceği konusunda daha fazla kontrol sahibi olmak istiyorsanız shouldOverrideUrlLoading yöntemini geçersiz kılan kendi WebViewClient öğenizi oluşturun. Aşağıdaki örnekte, MyWebViewClient sınıfının Activity sınıfının 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());

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şme varsa yöntem, false değerini döndürür ve URL yükleme işlemini geçersiz kılmaz. WebView, URL'yi her zamanki gibi yükler. URL ana makinesi eşleşmezse URL'leri işlemek için varsayılan Activity uygulamasını başlatan bir Intent oluşturulur. Bu intent, 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ı çözerken 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 doğru 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 ş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'si, öncelikle belirli URL'ler için intent'leri başlatmak amacıyla kullanılır. Bu API'yi uygularken WebView tarafından işlenen URL'ler için false döndürdüğünüzden emin olun. Ancak niyetleri başlatmakla sınırlı değilsiniz. Önceki kod örneklerinde, başlatma amaçlarını 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şini otomatik olarak toplar. goBack ve goForward tuşlarını kullanarak geçmişte geri ve ileri gidebilirsiniz.

Örneğin, aşağıdaki kodda Activity uygulamanı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ız Jetpack AppCompat 1.6.0 veya 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 web sayfası geçmişi varsa true değerini döndürür. Benzer şekilde, ileriye dönük geçmiş olup olmadığını kontrol etmek için canGoForward yöntemini kullanabilirsiniz. Bu kontrolü yapmazsanız kullanıcı geçmişin sonuna ulaştıktan sonra goBack ve goForward hiçbir şey yapmaz.

Etkinliğin yeniden oluşturulması veya arka plan işleminin geri alınması sırasında gezinme geçmişini korumak için saveState yöntemini kullanarak WebView'un gezinme geçmişini Bundle nesnesine serileştirin ve restoreState yöntemini kullanarak geri yükleyin. Kayıtlı durum boyutu sınırlarını güvenli bir şekilde yönetme ve TransactionTooLargeException hatasını önleme hakkında bilgi edinmek için WebView durumunu verimli bir şekilde yönetme başlıklı makaleyi inceleyin.

Cihaz yapılandırması 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 gerçekleşir. Bu değişiklikler, WebView nesnesinin etkinliğinin yok edilmesine ve yeni bir etkinlik oluşturulmasına neden olur. Bu işlem, yok edilen nesnenin URL'sini yükleyen yeni bir WebView nesnesi de oluşturur. Kullanıcının gezinme bağlamını geri yüklemek için onSaveInstanceState() içinde saveState ve yeniden oluşturma sırasında restoreState kullanabilirsiniz. Durum boyutunu güvenli bir şekilde yönetme stratejileri için WebView durumunu verimli bir şekilde yönetme başlıklı makaleyi inceleyin.

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 okuyun.

Pencereleri yönetin

Varsayılan olarak, yeni pencere açma istekleri yoksayılır. Bu durum, pencerelerin JavaScript tarafından veya bir bağlantıdaki hedef özelliği tarafından açılmasından bağımsız olarak geçerlidir. Birden fazla pencere açmak için kendi davranışınızı sağlamak üzere 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" değerini setSupportMultipleWindows yöntemine 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.

Belleği ve performansı yönetme

WebView, ayrı işlemlere ve yerel koda sahip Chromium tabanlı bir motor üzerinde çalıştığından temel bellek kullanımı standart Android görünümlerinden daha yüksektir. WebView örneklerini yeniden kullanmak ve bunları doğru şekilde yok etmek, uygulamanın kararlılığını korumak için çok önemlidir.

Web içeriği kullanırken uygulamanızın bellekte kapladığı yeri teşhis etme ve optimize etme hakkında daha fazla bilgi için WebView belleğini yönetme ve teşhis etme başlıklı makaleyi inceleyin.