Uygulamanızın internet üzerinden getirmek yerine statik olarak derlediğiniz içerikleri kullanması için web tabanlı içerik (ör. HTML, JavaScript ve CSS) sağlayabilirsiniz.
Uygulama içi içerikler internet erişimi gerektirmez veya kullanıcının bant genişliğini kullanmaz. İçerik yalnızca WebView
için özel olarak tasarlanmışsa, yani yerel bir uygulamayla iletişim kurulması gerekiyorsa kullanıcılar içeriği bir web tarayıcısında yanlışlıkla yükleyemezler.
Ancak uygulama içi içeriğin bazı dezavantajları vardır. Web tabanlı içeriği güncellemek için yeni bir uygulama güncellemesinin gönderilmesi gerekir ve kullanıcıların eski uygulama sürümleri varsa web sitesindekilerle cihazınızdaki uygulamanın içeriği arasında uyuşmazlık olma ihtimali vardır.
WebViewÖğeYükleyicisi
WebViewAssetLoader
, uygulama içi içeriği bir WebView
nesnesine yüklemenin esnek ve etkili bir yoludur. Bu sınıf aşağıdakileri destekler:
- Aynı kaynak politikasıyla uyumluluk için HTTP(S) URL'si ile içerik yükleme.
- JavaScript, CSS, resimler ve iframe'ler gibi alt kaynaklar yükleme.
WebViewAssetLoader
uygulamasını ana etkinlik dosyanıza ekleyin. Aşağıda, items klasöründen basit web içeriği yüklemeye ilişkin bir örnek verilmiştir:
Kotlin
private class LocalContentWebViewClient(private val assetLoader: WebViewAssetLoader) : WebViewClientCompat() { @RequiresApi(21) override fun shouldInterceptRequest( view: WebView, request: WebResourceRequest ): WebResourceResponse? { return assetLoader.shouldInterceptRequest(request.url) } // To support API < 21. override fun shouldInterceptRequest( view: WebView, url: String ): WebResourceResponse? { return assetLoader.shouldInterceptRequest(Uri.parse(url)) } }
Java
private static class LocalContentWebViewClient extends WebViewClientCompat { private final WebViewAssetLoader mAssetLoader; LocalContentWebViewClient(WebViewAssetLoader assetLoader) { mAssetLoader = assetLoader; } @Override @RequiresApi(21) public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) { return mAssetLoader.shouldInterceptRequest(request.getUrl()); } @Override @SuppressWarnings("deprecation") // To support API < 21. public WebResourceResponse shouldInterceptRequest(WebView view, String url) { return mAssetLoader.shouldInterceptRequest(Uri.parse(url)); } }
Uygulamanız, ihtiyaçlarına uygun bir WebViewAssetLoader
örneği yapılandırmalıdır. Sonraki bölümde
bir örnek verilmiştir.
Uygulama içi öğeler ve kaynaklar oluşturun
WebViewAssetLoader
, belirli bir kaynak yoluna karşılık gelen kaynakları yüklemek için PathHandler
örneklerinden yararlanır. Uygulamanızın ihtiyaç duyduğu kaynakları almak için bu arayüzü kullanabilirsiniz. Ancak Webkit kitaplığı, Android öğelerini ve kaynaklarını yüklemek için sırasıyla AssetsPathHandler
ve ResourcesPathHandler
paketlerini kullanabilir.
Başlamak için uygulamanız için öğeler ve kaynaklar oluşturun. Genellikle aşağıdakiler geçerlidir:
- HTML, JavaScript ve CSS gibi metin dosyaları öğelere aittir.
- Görüntüler ve diğer ikili dosyalar kaynaklara aittir.
Bir projeye metin tabanlı web dosyaları eklemek için şunları yapın:
- Android Studio'da uygulama > src > ana klasörü sağ tıklayın ve Yeni > Dizin'i seçin.
- Klasöre "assets" adını verin.
- assets klasörünü sağ tıklayın, ardından Yeni > Dosya'yı tıklayın.
index.html
yazıp Return veya Enter tuşuna basın. stylesheet.css
için boş bir dosya oluşturmak üzere önceki adımı tekrarlayın.- Oluşturduğunuz boş dosyaları sonraki iki kod örneğindeki içerikle doldurun.
```html
<!-- index.html content -->
<html>
<head>
<!-- Tip: Use relative URLs when referring to other in-app content to give
your app code the flexibility to change the scheme or domain as
necessary. -->
<link rel="stylesheet" href="/assets/stylesheet.css">
</head>
<body>
<p>This file is loaded from in-app content.</p>
<p><img src="/res/drawable/android_robot.png" alt="Android robot" width="100"></p>
</body>
</html>
```
```css
<!-- stylesheet.css content -->
body {
background-color: lightblue;
}
```
Projenize görüntü tabanlı bir web dosyası eklemek için aşağıdakileri yapın:
Android_symbol_green_RGB.png
dosyasını yerel makinenize indirin.Dosyanın adını
android_robot.png
olarak değiştirin.Dosyayı, projenizin sabit diskinizdeki
main/res/drawable
dizinine manuel olarak taşıyın.
Şekil 4'te, eklediğiniz resim ve bir uygulamada oluşturulmuş önceki kod örneklerindeki metin gösterilmektedir.
Uygulamayı tamamlamak için aşağıdakileri yapın:
İşleyicileri kaydedin ve aşağıdaki kodu
onCreate()
yöntemine ekleyerekAssetLoader
özelliğini yapılandırın:Kotlin
val assetLoader = WebViewAssetLoader.Builder() .addPathHandler("/assets/", AssetsPathHandler(this)) .addPathHandler("/res/", ResourcesPathHandler(this)) .build() webView.webViewClient = LocalContentWebViewClient(assetLoader)
Java
final WebViewAssetLoader assetLoader = new WebViewAssetLoader.Builder() .addPathHandler("/assets/", new WebViewAssetLoader.AssetsPathHandler(this)) .addPathHandler("/res/", new WebViewAssetLoader.ResourcesPathHandler(this)) .build(); mWebView.setWebViewClient(new LocalContentWebViewClient(assetLoader));
Aşağıdaki kodu
onCreate()
yöntemine ekleyerek içeriği yükleyin:Kotlin
webView.loadUrl("https://appassets.androidplatform.net/assets/index.html")
Java
mWebView.loadUrl("https://appassets.androidplatform.net/assets/index.html");
Uygulama içi içeriği web sitenizdeki kaynaklarla birlikte kullanın
Uygulamanızın, uygulama içi ve internetteki içeriğin (ör. web sitenizin CSS'si tarafından stilize edilmiş bir uygulama içi HTML sayfası) bir karışımını yüklemesi gerekebilir.
WebViewAssetLoader
bu kullanım alanını destekler. Kayıtlı PathHandler
örneklerinden hiçbiri belirtilen yol için bir kaynak bulamazsa WebView
, internetten içerik yüklemeye geri döner. Uygulama içi içeriği web sitenizdeki kaynaklarla karışık olarak kullanıyorsanız uygulama içi kaynaklar için /assets/
veya /resources/
gibi dizin yollarını ayırın. Web sitenizdeki kaynakları bu konumlarda depolamaktan kaçının.
Kotlin
val assetLoader = WebViewAssetLoader.Builder() .setDomain("example.com") // Replace this with your website's domain. .addPathHandler("/assets/", AssetsPathHandler(this)) .build() webView.webViewClient = LocalContentWebViewClient(assetLoader) val inAppHtmlUrl = "https://example.com/assets/index.html" webView.loadUrl(inAppHtmlUrl) val websiteUrl = "https://example.com/website/data.json" // JavaScript code to fetch() content from the same origin. val jsCode = "fetch('$websiteUrl')" + ".then(resp => resp.json())" + ".then(data => console.log(data));" webView.evaluateJavascript(jsCode, null)
Java
final WebViewAssetLoader assetLoader = new WebViewAssetLoader.Builder() .setDomain("example.com") // Replace this with your website's domain. .addPathHandler("/assets/", new AssetsPathHandler(this)) .build(); mWebView.setWebViewClient(new LocalContentWebViewClient(assetLoader)); String inAppHtmlUrl = "https://example.com/assets/index.html"; mWebView.loadUrl(inAppHtmlUrl); String websiteUrl = "https://example.com/website/data.json"; // JavaScript code to fetch() content from the same origin. String jsCode = "fetch('" + websiteUrl + "')" + ".then(resp => resp.json())" + ".then(data => console.log(data));"; mWebView.evaluateJavascript(jsCode, null);
Web tarafından barındırılan JSON verilerini getiren bir uygulama içi HTML sayfası örneği için GitHub'daki WebView
demosuna göz atın.
Taban URL'si ile birlikteyüklenenVeriler
Uygulamanızın yalnızca bir HTML sayfası yüklemesi ve alt kaynaklara müdahale etmesi gerekmiyorsa uygulama öğeleri gerektirmeyen loadDataWithBaseURL()
'ı kullanmayı düşünün. Bunu aşağıdaki kod örneğinde gösterildiği gibi kullanabilirsiniz:
Kotlin
val html = "<html><body><p>Hello world</p></body></html>" val baseUrl = "https://example.com/" webView.loadDataWithBaseURL(baseUrl, html, "text/html", null, baseUrl)
Java
String html = "<html><body><p>Hello world</p></body></html>"; String baseUrl = "https://example.com/"; mWebView.loadDataWithBaseURL(baseUrl, html, "text/html", null, baseUrl);
Bağımsız değişken değerlerini dikkatli bir şekilde seçin. Aşağıdakileri göz önünde bulundurun:
baseUrl
: HTML içeriğinizin yüklendiği URL'dir. Bu bir HTTP(S) URL'si olmalıdır.data
: Dize olarak görüntülemek istediğiniz HTML içeriğidir.mimeType
: Bu genellikletext/html
olarak ayarlanmalıdır.encoding
:baseUrl
bir HTTP(S) URL'si olduğunda kullanılmaz. Bu nedenlenull
olarak ayarlanabilir.historyUrl
:baseUrl
ile aynı değere ayarlandı.
Uygulamanızın aynı kaynak politikasına uyduğundan emin olmanıza yardımcı olduğundan, baseUrl
olarak HTTP(S) URL'si kullanmanızı önemle tavsiye ederiz.
İçeriğiniz için uygun bir baseUrl
bulamıyorsanız ve loadData()
kullanmayı tercih ediyorsanız yüzde kodlaması veya Base64 kodlaması ile içeriği kodlamanız gerekir.
Aşağıdaki kod örneğinde gösterildiği gibi bunu programatik olarak kodlamak için Base64 kodlamasını seçmenizi ve Android API'lerini kullanmanızı önemle tavsiye ederiz:
Kotlin
val encodedHtml: String = Base64.encodeToString(html.toByteArray(), Base64.NO_PADDING) webView.loadData(encodedHtml, mimeType, "base64")
Java
String encodedHtml = Base64.encodeToString(html.getBytes(), Base64.NO_PADDING); mWebView.loadData(encodedHtml, mimeType, "base64");
Kaçınılması gerekenler
Uygulama içi içerik yüklemenin başka yolları da vardır, ancak bunlara karşı şiddetle davranmanızı öneririz:
file://
URL'ler vedata:
URL'ler, opak kaynaklar olarak kabul edilir. Dolayısıylafetch()
veyaXMLHttpRequest
gibi güçlü web API'lerinden yararlanamazlar.loadData()
dahili olarakdata:
URL'si kullandığından bunun yerineWebViewAssetLoader
veyaloadDataWithBaseURL()
kullanmanızı öneririz.WebSettings.setAllowFileAccessFromFileURLs()
veWebSettings.setAllowUniversalAccessFromFileURLs()
file://
URL'leriyle ilgili sorunlar giderilebiliyor olsa da, bu sorunlarıtrue
olarak ayarlamanız önerilmez. Bunu yaparsanız uygulamanız dosya tabanlı istismarlara karşı savunmasız hale gelir. En güçlü güvenlik için bunları tüm API düzeylerinde açıkçafalse
olarak ayarlamanızı öneririz.- Aynı nedenlerle
file://android_assets/
vefile://android_res/
URL'lerini kullanmamanızı öneririz.AssetsHandler
veResourcesHandler
sınıfları, bunların yerini alacak şekilde tasarlanmıştır. MIXED_CONTENT_ALWAYS_ALLOW
kullanmaktan kaçının. Bu ayar genellikle gerekli değildir ve uygulamanızın güvenliğini zayıflatır. Uygulama içi içeriğinizi web sitenizin kaynaklarıyla aynı şema (HTTP veya HTTPS) üzerinden yüklemenizi ve uygun şekildeMIXED_CONTENT_COMPATIBILITY_MODE
veyaMIXED_CONTENT_NEVER_ALLOW
kullanmanızı öneririz.