میتوانید محتوای مبتنی بر وب مانند HTML، جاوا اسکریپت و CSS را برای برنامهتان فراهم کنید تا بهجای واکشی از طریق اینترنت، بهصورت ایستا در برنامه کامپایل کنید.
محتوای درون برنامه ای نیازی به دسترسی به اینترنت یا مصرف پهنای باند کاربر ندارد. اگر محتوا به طور خاص فقط برای WebView طراحی شده باشد - یعنی به برقراری ارتباط با یک برنامه بومی بستگی دارد - کاربران نمی توانند به طور تصادفی آن را در یک مرورگر وب بارگذاری کنند.
با این حال، برخی از اشکالات در محتوای درون برنامه وجود دارد. بهروزرسانی محتوای مبتنی بر وب نیاز به ارسال بهروزرسانی جدید برنامه دارد و اگر کاربران نسخههای قدیمی برنامه را داشته باشند، احتمال عدم تطابق محتوای بین آنچه در وبسایت و آنچه در برنامه موجود است در دستگاه شما وجود دارد.
WebViewAssetLoader
WebViewAssetLoader یک روش منعطف و کارآمد برای بارگیری محتوای درون برنامه در یک شی WebView است. این کلاس موارد زیر را پشتیبانی می کند:
- در حال بارگیری محتوا با یک URL HTTP(S) برای سازگاری با خط مشی مبدا یکسان .
- بارگیری منابع فرعی مانند جاوا اسکریپت، CSS، تصاویر و iframes.
WebViewAssetLoader در فایل فعالیت اصلی خود قرار دهید. در زیر نمونه ای از بارگیری محتوای وب ساده از پوشه assets آورده شده است:
کاتلین
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)) } }
جاوا
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)); } }
برنامه شما باید یک نمونه WebViewAssetLoader را مطابق با نیازهای خود پیکربندی کند. بخش بعدی یک مثال دارد.
دارایی ها و منابع درون برنامه ای ایجاد کنید
WebViewAssetLoader به نمونه های PathHandler برای بارگیری منابع مربوط به یک مسیر منبع داده شده متکی است. اگرچه میتوانید این رابط را برای بازیابی منابع مورد نیاز برنامه خود پیادهسازی کنید، کتابخانه Webkit به ترتیب AssetsPathHandler و ResourcesPathHandler را برای بارگیری داراییها و منابع Android دستهبندی میکند.
برای شروع، دارایی ها و منابعی را برای برنامه خود ایجاد کنید. به طور کلی موارد زیر اعمال می شود:
- فایل های متنی مانند HTML، جاوا اسکریپت و CSS به دارایی ها تعلق دارند.
- تصاویر و سایر فایل های باینری متعلق به منابع هستند.
برای افزودن فایل های وب مبتنی بر متن به پروژه، موارد زیر را انجام دهید:
- در Android Studio، روی برنامه > src > پوشه اصلی کلیک راست کرده و سپس New > Directory را انتخاب کنید.

شکل 1. یک پوشه دارایی برای پروژه خود ایجاد کنید. - نام پوشه را "assets" بگذارید.

شکل 2. پوشه assets را نام ببرید. - روی پوشه assets کلیک راست کرده و سپس New > File را کلیک کنید.
index.htmlرا وارد کرده و کلید Return یا Enter را فشار دهید.
شکل 3. فایل index.htmlایجاد کنید. - مرحله قبل را برای ایجاد یک فایل خالی برای
stylesheet.cssتکرار کنید. - فایل های خالی که ایجاد کرده اید را با محتوا در دو نمونه کد بعدی پر کنید.
```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;
}
```
برای افزودن یک فایل وب مبتنی بر تصویر به پروژه خود، موارد زیر را انجام دهید:
فایل
Android_symbol_green_RGB.pngرا در دستگاه محلی خود دانلود کنید.نام فایل را به
android_robot.pngتغییر دهید.فایل را به صورت دستی به دایرکتوری
main/res/drawableپروژه خود در هارد دیسک منتقل کنید.
شکل 4 تصویری را که اضافه کردید و متن نمونه کدهای قبلی ارائه شده در یک برنامه را نشان می دهد.

برای تکمیل برنامه، موارد زیر را انجام دهید:
هندلرها را ثبت کرده و
AssetLoaderرا با افزودن کد زیر به متدonCreate()پیکربندی کنید:کاتلین
val assetLoader = WebViewAssetLoader.Builder() .addPathHandler("/assets/", AssetsPathHandler(this)) .addPathHandler("/res/", ResourcesPathHandler(this)) .build() webView.webViewClient = LocalContentWebViewClient(assetLoader)
جاوا
final WebViewAssetLoader assetLoader = new WebViewAssetLoader.Builder() .addPathHandler("/assets/", new WebViewAssetLoader.AssetsPathHandler(this)) .addPathHandler("/res/", new WebViewAssetLoader.ResourcesPathHandler(this)) .build(); mWebView.setWebViewClient(new LocalContentWebViewClient(assetLoader));
با افزودن کد زیر به متد
onCreate()محتوا را بارگیری کنید:کاتلین
webView.loadUrl("https://appassets.androidplatform.net/assets/index.html")
جاوا
mWebView.loadUrl("https://appassets.androidplatform.net/assets/index.html");
محتوای درون برنامه ای را با منابع وب سایت خود ترکیب کنید
ممکن است برنامه شما نیاز به بارگیری ترکیبی از محتوا و محتوای درون برنامه ای از اینترنت داشته باشد، مانند صفحه HTML درون برنامه ای که توسط CSS وب سایت شما طراحی شده است. WebViewAssetLoader از این مورد استفاده پشتیبانی می کند. اگر هیچ یک از نمونه های ثبت شده PathHandler نتواند منبعی برای مسیر داده شده پیدا کند، WebView به بارگیری محتوا از اینترنت بازمی گردد. اگر محتوای درون برنامه ای را با منابع وب سایت خود ترکیب می کنید، مسیرهای دایرکتوری مانند /assets/ یا /resources/ را برای منابع درون برنامه ذخیره کنید. از ذخیره هرگونه منبع از وب سایت خود در آن مکان ها خودداری کنید.
کاتلین
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)
جاوا
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);
برای نمونهای از صفحه HTML درونبرنامهای که دادههای JSON میزبان وب را واکشی میکند ، نسخه نمایشی WebView را در GitHub ببینید.
loadDataWithBaseURL
وقتی برنامه شما فقط نیاز به بارگیری یک صفحه HTML دارد و نیازی به رهگیری منابع فرعی ندارد، از loadDataWithBaseURL() استفاده کنید که به دارایی های برنامه نیاز ندارد. همانطور که در نمونه کد زیر نشان داده شده است می توانید از آن استفاده کنید:
کاتلین
val html = "<html><body><p>Hello world</p></body></html>" val baseUrl = "https://example.com/" webView.loadDataWithBaseURL(baseUrl, html, "text/html", null, baseUrl)
جاوا
String html = "<html><body><p>Hello world</p></body></html>"; String baseUrl = "https://example.com/"; mWebView.loadDataWithBaseURL(baseUrl, html, "text/html", null, baseUrl);
مقادیر آرگومان را با دقت انتخاب کنید. موارد زیر را در نظر بگیرید:
-
baseUrl: این نشانی اینترنتی است که محتوای HTML شما با آن بارگذاری می شود. این باید یک URL HTTP(S) باشد. -
data: این محتوای HTML است که می خواهید به عنوان یک رشته نمایش دهید. -
mimeType: معمولاً باید رویtext/htmlتنظیم شود. -
encoding: زمانی کهbaseUrlیک URL HTTP(S) باشد استفاده نمی شود، بنابراین می توان آن را رویnullتنظیم کرد. -
historyUrl: این مقدار به همان مقدارbaseUrlتنظیم می شود.
ما اکیداً توصیه میکنیم از URL HTTP(S) بهعنوان baseUrl استفاده کنید، زیرا این امر به شما کمک میکند تا مطمئن شوید که برنامه شما با خطمشی همان مبدا مطابقت دارد.
اگر نمی توانید یک baseUrl مناسب برای محتوای خود پیدا کنید و ترجیح می دهید از loadData() استفاده کنید، باید محتوا را با رمزگذاری درصد یا Base64 رمزگذاری کنید. همانطور که در نمونه کد زیر نشان داده شده است، اکیداً توصیه میکنیم رمزگذاری Base64 را انتخاب کنید و از APIهای Android برای رمزگذاری برنامهای آن استفاده کنید:
کاتلین
val encodedHtml: String = Base64.encodeToString(html.toByteArray(), Base64.NO_PADDING) webView.loadData(encodedHtml, mimeType, "base64")
جاوا
String encodedHtml = Base64.encodeToString(html.getBytes(), Base64.NO_PADDING); mWebView.loadData(encodedHtml, mimeType, "base64");
چیزهایی که باید اجتناب کرد
چندین راه دیگر برای بارگیری محتوای درون برنامه ای وجود دارد، اما ما به شدت توصیه می کنیم که از آنها جلوگیری کنید:
-
file://آدرسها وdata:نشانیهای اینترنتی منشأ غیرشفاف در نظر گرفته میشوند، به این معنی که نمیتوانند از APIهای وب قدرتمند مانندfetch()یاXMLHttpRequestاستفاده کنند.loadData()به صورت داخلی ازdata:URL ها، بنابراین ما توصیه می کنیم به جای آن ازWebViewAssetLoaderیاloadDataWithBaseURL()استفاده کنید. - اگرچه
WebSettings.setAllowFileAccessFromFileURLs()وWebSettings.setAllowUniversalAccessFromFileURLs()می توانند مشکلات مربوط به URL هایfile://کنند، توصیه می کنیم این موارد را رویtrueتنظیم نکنید زیرا انجام این کار برنامه شما را در برابر سوء استفاده های مبتنی بر فایل آسیب پذیر می کند. توصیه میکنیم به صراحت این موارد را رویfalseدر تمام سطوح API برای قویترین امنیت تنظیم کنید. - به همین دلایل، ما توصیه می کنیم از URL های
file://android_assets/وfile://android_res/جلوگیری کنید. کلاسهایAssetsHandlerوResourcesHandlerقرار است جایگزینهای کشویی باشند. - از استفاده از
MIXED_CONTENT_ALWAYS_ALLOWخودداری کنید. این تنظیم معمولاً ضروری نیست و امنیت برنامه شما را ضعیف می کند. توصیه میکنیم محتوای درونبرنامه خود را از طریق همان طرح (HTTP یا HTTPS) بهعنوان منابع وبسایت خود بارگیری کنید و در صورت لزوم ازMIXED_CONTENT_COMPATIBILITY_MODEیاMIXED_CONTENT_NEVER_ALLOWاستفاده کنید.