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

Bir web uygulamasını veya web sayfasını bir istemci uygulamasının parçası olarak teslim etmek için WebView'i kullanın. WebView sınıfı, web sayfalarını etkinlik düzeninizin bir parçası olarak görüntülemenize olanak tanıyan, Android View sınıfının bir uzantısıdır. Gezinme denetimleri veya adres çubuğu gibi tam gelişmiş bir web tarayıcısına ait özellikleri içermez. Varsayılan olarak yalnızca WebView 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 daha sonra bu öğeyi, online barındırılan dokümanınızı görüntülemek için kullanabilirsiniz.

Uygulamanız, e-posta gibi verileri almak için internet bağlantısı gerektiren bir kullanıcıya veri sağladığında da WebView size yardımcı olabilir. Bu durumda, Android uygulamanızda bir ağ isteği gerçekleştirdikten sonra verileri ayrıştırıp Android düzeninde oluşturmak yerine 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 uygun bir web sayfası tasarlayabilir ve daha sonra, Android uygulamanıza 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ızdaki istemci tarafı koda nasıl bağlayacağınız, sayfada gezinmenin nasıl işleneceği 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üvenle 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.

Bunu build.gradle dosyanıza aşağıdaki şekilde 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ğine göz atın.

Uygulamanıza Web Görünümü ekleyin

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üzeninde bir Web Görünümü ekleme

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

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

Bir web sayfasını WebView içinde 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şlevinde bir Web Görünümü 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 manifest dosyanızda INTERNET iznini aşağıdaki örnekte gösterildiği gibi isteyin:

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

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

  • WebChromeClient ile 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 (ör. 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ünü okuyun.
  • WebViewClient kullanarak form gönderimlerindeki veya gezinmedeki hatalar gibi içerik oluşturmayı etkileyen etkinlikleri işleme. Bu alt sınıfı, URL yüklemesini engellemek için de kullanabilirsiniz.
  • WebSettings öğesini değiştirerek JavaScript'i etkinleştirme.
  • Bir WebView içine eklediğiniz Android çerçeve nesnelerine erişmek için JavaScript'i kullanma.

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, varsayılan olarak WebView içinde devre dışıdır. Bu özelliği, WebView ekli WebSettings üzerinden etkinleştirebilirsiniz. getSettings() ile WebSettings kodunu 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, kullanışlı bulabileceğiniz diğer ayarlara erişim sağlar. Örneğin, Android uygulamanızda özellikle WebView için tasarlanmış bir web uygulaması geliştiriyorsanız setUserAgentString() ile bir özel kullanıcı aracısı dizesi tanımlayabilir ve ardından web sayfanızdaki ö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ızda özel olarak WebView için 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() yöntemini çağırın. Bunu, JavaScript'inize bağlamak üzere bir sınıf örneği ve JavaScript'inizin sınıfa erişmek için çağırabileceği bir arayüz adı iletir.

Örneğin, aşağıdaki sınıfı Android uygulamanıza 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ını sağlar.

Bu sınıfı aşağıdaki örnekte gösterildiği gibi, WebView uygulamanızda çalışan JavaScript'e addJavascriptInterface() ile 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'i aşağıda 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, sayfayı web sayfanızda otomatik olarak kullanılabilir hale getirir. Dolayısıyla, 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 içindeki bir web sayfasındaki 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ı hedef URL'yi açıp 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 saklanan 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ıza yüklenir. Tıklanan bir bağlantının nereye yüklendiğ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 öğesinin bir iç sınıfı Activity 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, URL ana makinesinin önceki örnekte tanımlandığı gibi belirli bir alan adıyla eşleşip eşleşmediğini kontrol eden shouldOverrideUrlLoading() yöntemini çağırır. Eşleşirse yöntem false döndürür ve URL yüklemesini geçersiz kılmaz. WebView, URL'yi her zamanki gibi yükleyebilir. URL ana makinesi eşleşmiyorsa URL'lerin işlenmesine yönelik varsayılan Activity API'sini başlatmak için bir Intent oluşturulur. Bu işlem, 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österilene benzer geçersiz URL'ler, WebView içinde tutarsız bir şekilde işlendiğinden bunun yerine iyi biçimlendirilmiş bir URL kullanmanızı öneririz. Kuruluşunuzun kontrol ettiği bir alan adı için özel şema veya HTTPS URL'si kullanabilirsiniz.

Önceki örnekte olduğu gibi bağlantıda basit bir dize yerine aşağıdaki gibi bir özel ş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'sinin temel amacı belirli URL'ler için amaçları başlatmaktır. API'yi uygularken, WebView tarafından işlenen URL'ler için false döndürdüğünüzden emin olun. Ancak siz niyet başlatmakla sınırlı değilsiniz. Başlatma amaçlarını, önceki kod örneklerindeki herhangi bir özel davranışla değiştirebilirsiniz.

WebView öğeniz 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ız AndroidX AppCompat 1.6.0 veya sonraki bir sürümü 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();
    }
}

Kullanıcının ziyaret edebileceği web sayfası geçmişi varsa canGoBack() yöntemi "doğru" 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ü gerçekleştirmezseniz 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 sırasında, kullanıcıların cihazı döndürmesi veya bir giriş yöntemi düzenleyicisini (IME) kapatması gibi cihazın yapılandırması değiştiğinde etkinlik durumu değişir. Bu değişiklikler, bir WebView nesnesinin etkinliğinin kaldırılmasına ve yeni bir etkinliğin oluşturulmasına neden olur. Bunun sonucunda, kaldırılan nesnenin URL'sini yükleyen yeni bir WebView nesnesi de oluşturulur. Etkinliğinizin varsayılan davranışını değiştirmek için manifest dosyanızdaki orientation değişikliklerini işleme şeklini değiştirebilirsiniz. Çalışma zamanı sırası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 bölümünü okuyun.

Pencereleri yönet

Varsayılan olarak, yeni pencere açma istekleri yoksayılır. Bu durum, bağlantıların JavaScript tarafından veya bir bağlantıdaki hedef özellik ile açılmasından bağımsız olarak geçerlidir. WebChromeClient öğenizi birden fazla pencere açmayla ilgili kendi davranışınızı sağlayacak şekilde özelleştirebilirsiniz.

Uygulamanızın daha güvenli olmasını sağlamak için pop-up'ların ve yeni pencerelerin açılmasını engellemek en iyisidir. Bu davranışı uygulamanın en güvenli yolu, "true" yöntemini setSupportMultipleWindows()'e geçirmek, ancak setSupportMultipleWindows() yönteminin 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.