WebView
برای ارائه یک برنامه وب یا یک صفحه وب به عنوان بخشی از برنامه مشتری استفاده کنید. کلاس WebView
یک برنامه افزودنی از کلاس View
اندروید است که به شما امکان می دهد صفحات وب را به عنوان بخشی از طرح فعالیت خود نمایش دهید. شامل ویژگیهای یک مرورگر وب کاملاً توسعهیافته، مانند کنترلهای پیمایش یا نوار آدرس نمیشود. تمام کاری که WebView
انجام می دهد، به طور پیش فرض، نمایش یک صفحه وب است.
WebView
می تواند به شما کمک کند اطلاعاتی را در برنامه خود ارائه دهید که ممکن است نیاز به به روز رسانی داشته باشید، مانند قرارداد کاربر نهایی یا راهنمای کاربر. در برنامه Android خود، میتوانید یک Activity
ایجاد کنید که حاوی WebView
است، سپس از آن برای نمایش سند خود که به صورت آنلاین میزبانی شده است استفاده کنید.
WebView
همچنین می تواند زمانی که برنامه شما داده هایی را در اختیار کاربر قرار می دهد که برای بازیابی داده ها به اتصال اینترنت نیاز دارد، مانند ایمیل، کمک کند. در این مورد، ممکن است متوجه شوید که ساخت یک WebView
در برنامه اندرویدی خود که یک صفحه وب را با تمام داده های کاربر نشان می دهد، به جای انجام یک درخواست شبکه، و سپس تجزیه داده ها و رندر کردن آن در یک طرح بندی اندروید، آسان تر است. در عوض، میتوانید یک صفحه وب طراحی کنید که برای دستگاههای مجهز به Android طراحی شده است و سپس یک WebView
در برنامه Android خود پیاده کنید که صفحه وب را بارگیری میکند.
این سند نحوه شروع به کار با WebView
، نحوه اتصال جاوا اسکریپت از صفحه وب خود به کد سمت سرویس گیرنده در برنامه Android خود، نحوه مدیریت پیمایش صفحه، و نحوه مدیریت ویندوز هنگام استفاده از WebView
را شرح می دهد.
با WebView در نسخه های قبلی اندروید کار کنید
برای استفاده ایمن از قابلیتهای WebView
جدیدتر در دستگاهی که برنامه شما روی آن اجرا میشود، کتابخانه AndroidX Webkit را اضافه کنید. این یک کتابخانه ثابت است که می توانید برای استفاده از API های android.webkit
که برای نسخه های پلتفرم قبلی در دسترس نیستند، به برنامه خود اضافه کنید.
به صورت زیر آن را به فایل build.gradle
خود اضافه کنید:
کاتلین
dependencies { implementation("androidx.webkit:webkit:1.8.0") }
شیار
dependencies { implementation ("androidx.webkit:webkit:1.8.0") }
برای جزئیات بیشتر ، مثال WebView
در GitHub کاوش کنید.
یک WebView به برنامه خود اضافه کنید
برای افزودن WebView
به برنامه خود، میتوانید عنصر <WebView>
را در طرحبندی فعالیت خود وارد کنید یا کل پنجره Activity
را به عنوان WebView
در onCreate()
تنظیم کنید.
یک WebView در طرحبندی فعالیت اضافه کنید
برای افزودن WebView
به برنامه خود در طرحبندی، کد زیر را به فایل XML طرحبندی فعالیت خود اضافه کنید:
<WebView android:id="@+id/webview" android:layout_width="match_parent" android:layout_height="match_parent" />
برای بارگذاری یک صفحه وب در WebView
، از loadUrl()
استفاده کنید، همانطور که در مثال زیر نشان داده شده است:
کاتلین
val myWebView: WebView = findViewById(R.id.webview) myWebView.loadUrl("http://www.example.com")
جاوا
WebView myWebView = (WebView) findViewById(R.id.webview); myWebView.loadUrl("http://www.example.com");
افزودن WebView در onCreate()
برای افزودن WebView
به برنامه خود در روش onCreate()
یک فعالیت، از منطقی شبیه به زیر استفاده کنید:
کاتلین
val myWebView = WebView(activityContext) setContentView(myWebView)
جاوا
WebView myWebView = new WebView(activityContext); setContentView(myWebView);
سپس صفحه را بارگذاری کنید:
کاتلین
myWebView.loadUrl("http://www.example.com")
جاوا
myWebView.loadUrl("https://www.example.com");
یا URL را از یک رشته HTML بارگیری کنید:
کاتلین
// 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")
جاوا
// 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");
برنامه شما باید به اینترنت دسترسی داشته باشد. برای دسترسی به اینترنت، همانطور که در مثال زیر نشان داده شده است، مجوز INTERNET
را در فایل مانیفست خود درخواست کنید:
<manifest ... > <uses-permission android:name="android.permission.INTERNET" /> ... </manifest>
با انجام یکی از موارد زیر می توانید WebView
خود را سفارشی کنید:
- فعال کردن پشتیبانی تمام صفحه با استفاده از
WebChromeClient
. این کلاس همچنین زمانی فراخوانی می شود کهWebView
برای تغییر رابط کاربری برنامه میزبان، مانند ایجاد یا بستن پنجره ها یا ارسال گفتگوهای جاوا اسکریپت به کاربر، به مجوز نیاز دارد. برای کسب اطلاعات بیشتر در مورد اشکال زدایی در این زمینه، Debug web apps را بخوانید. - مدیریت رویدادهایی که بر رندر محتوا تأثیر میگذارند، مانند خطاهایی در ارسال فرم یا پیمایش با استفاده از
WebViewClient
. شما همچنین می توانید از این زیر کلاس برای جلوگیری از بارگذاری URL استفاده کنید. - فعال کردن جاوا اسکریپت با تغییر
WebSettings
. - استفاده از جاوا اسکریپت برای دسترسی به اشیاء چارچوب Android که به
WebView
تزریق کرده اید.
از جاوا اسکریپت در WebView استفاده کنید
اگر صفحه وبی که می خواهید در WebView
خود بارگیری کنید از جاوا اسکریپت استفاده می کند، باید جاوا اسکریپت را برای WebView
خود فعال کنید. پس از فعال کردن جاوا اسکریپت، می توانید بین کد برنامه و کد جاوا اسکریپت خود رابط ایجاد کنید.
جاوا اسکریپت را فعال کنید
جاوا اسکریپت در WebView
به طور پیش فرض غیرفعال است. میتوانید آن را از طریق WebSettings
متصل به WebView
خود فعال کنید. WebSettings
با getSettings()
بازیابی کنید، سپس جاوا اسکریپت را با setJavaScriptEnabled()
فعال کنید.
مثال زیر را ببینید:
کاتلین
val myWebView: WebView = findViewById(R.id.webview) myWebView.settings.javaScriptEnabled = true
جاوا
WebView myWebView = (WebView) findViewById(R.id.webview); WebSettings webSettings = myWebView.getSettings(); webSettings.setJavaScriptEnabled(true);
WebSettings
دسترسی به تنظیمات مختلفی را فراهم می کند که ممکن است برای شما مفید باشد. به عنوان مثال، اگر در حال توسعه یک برنامه وب هستید که به طور خاص برای WebView
در برنامه Android شما طراحی شده است، می توانید یک رشته عامل سفارشی کاربر با setUserAgentString()
تعریف کنید، سپس از عامل کاربر سفارشی در صفحه وب خود پرس و جو کنید تا تأیید کنید که مشتری درخواست کننده صفحه وب شما برنامه اندروید شما است.
کد جاوا اسکریپت را به کد اندروید متصل کنید
هنگام توسعه یک برنامه وب که به طور خاص برای WebView
در برنامه Android شما طراحی شده است، می توانید رابط هایی بین کد جاوا اسکریپت و کد اندروید سمت سرویس گیرنده ایجاد کنید. به عنوان مثال، کد جاوا اسکریپت شما می تواند به جای استفاده از تابع alert()
جاوا اسکریپت، متدی را در کد اندروید شما برای نمایش Dialog
فراخوانی کند.
برای اتصال یک رابط جدید بین کد جاوا اسکریپت و کد اندروید، addJavascriptInterface()
را فراخوانی کنید و آن را یک نمونه کلاس ارسال کنید تا به جاوا اسکریپت متصل شود و نام رابطی که جاوا اسکریپت شما می تواند برای دسترسی به کلاس فراخوانی کند.
به عنوان مثال، می توانید کلاس زیر را در برنامه اندروید خود قرار دهید:
کاتلین
/** 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() } }
جاوا
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(); } }
در این مثال، کلاس WebAppInterface
به صفحه وب اجازه می دهد تا با استفاده از متد showToast()
یک پیام Toast
ایجاد کند.
می توانید این کلاس را به جاوا اسکریپتی که در WebView
شما اجرا می شود با addJavascriptInterface()
متصل کنید، همانطور که در مثال زیر نشان داده شده است:
کاتلین
val webView: WebView = findViewById(R.id.webview) webView.addJavascriptInterface(WebAppInterface(this), "Android")
جاوا
WebView webView = (WebView) findViewById(R.id.webview); webView.addJavascriptInterface(new WebAppInterface(this), "Android");
این یک رابط به نام Android
برای جاوا اسکریپت در حال اجرا در WebView
ایجاد می کند. در این مرحله، برنامه وب شما به کلاس WebAppInterface
دسترسی دارد. به عنوان مثال، در اینجا برخی از HTML و جاوا اسکریپت وجود دارد که وقتی کاربر روی دکمه ای ضربه می زند، یک پیام نان تست با استفاده از رابط جدید ایجاد می کند:
<input type="button" value="Say hello" onClick="showAndroidToast('Hello Android!')" /> <script type="text/javascript"> function showAndroidToast(toast) { Android.showToast(toast); } </script>
نیازی به مقداردهی اولیه رابط Android
از جاوا اسکریپت نیست. WebView
به طور خودکار آن را در دسترس صفحه وب شما قرار می دهد. بنابراین، وقتی کاربر روی دکمه ضربه میزند، تابع showAndroidToast()
از رابط Android
برای فراخوانی متد WebAppInterface.showToast()
استفاده میکند.
ناوبری صفحه را مدیریت کنید
وقتی کاربر روی پیوندی از یک صفحه وب در WebView
شما ضربه میزند، بهطور پیشفرض، Android برنامهای را راهاندازی میکند که URLها را مدیریت میکند. معمولاً مرورگر وب پیشفرض URL مقصد را باز کرده و بارگذاری میکند. با این حال، میتوانید این رفتار را برای WebView
خود لغو کنید تا پیوندها در WebView
شما باز شوند. سپس می توانید به کاربر اجازه دهید در تاریخچه صفحه وب خود که توسط WebView
شما نگهداری می شود به عقب و جلو حرکت کند.
برای باز کردن پیوندهایی که کاربر روی آنها ضربه زده است، با استفاده از setWebViewClient()
یک WebViewClient
برای WebView
خود ارائه دهید. همه پیوندهایی که کاربر روی آنها ضربه می زند در WebView
شما بارگیری می شود. اگر می خواهید کنترل بیشتری روی مکان بارگیری پیوند کلیک شده داشته باشید، WebViewClient
خود را ایجاد کنید که متد shouldOverrideUrlLoading()
لغو می کند. مثال زیر فرض میکند که MyWebViewClient
یک کلاس داخلی از Activity
است.
کاتلین
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 } }
جاوا
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; } }
سپس یک نمونه از این WebViewClient
جدید برای WebView
ایجاد کنید:
کاتلین
val myWebView: WebView = findViewById(R.id.webview) myWebView.webViewClient = MyWebViewClient()
جاوا
WebView myWebView = (WebView) findViewById(R.id.webview); myWebView.setWebViewClient(new MyWebViewClient());
اکنون وقتی کاربر روی یک پیوند ضربه میزند، سیستم متد shouldOverrideUrlLoading()
را فراخوانی میکند که بررسی میکند آیا میزبان URL با یک دامنه خاص مطابقت دارد، همانطور که در مثال قبل تعریف شد. اگر مطابقت داشت، متد false را برمیگرداند و بارگذاری URL را لغو نمیکند. به WebView
اجازه میدهد URL را طبق معمول بارگیری کند. اگر میزبان URL مطابقت نداشته باشد، یک Intent
برای راه اندازی Activity
پیش فرض برای مدیریت URL ها ایجاد می شود که به مرورگر وب پیش فرض کاربر حل می شود.
آدرسهای اینترنتی سفارشی را مدیریت کنید
WebView
هنگام درخواست منابع و حل و فصل پیوندهایی که از یک طرح URL سفارشی استفاده می کنند، محدودیت هایی اعمال می کند. به عنوان مثال، اگر callbackهایی مانند shouldOverrideUrlLoading()
یا shouldInterceptRequest()
را پیاده سازی کنید، WebView
آنها را فقط برای URL های معتبر فراخوانی می کند.
برای مثال، WebView
ممکن است متد shouldOverrideUrlLoading()
شما را برای پیوندهایی مانند این فراخوانی نکند:
<a href="showProfile">Show Profile</a>
نشانیهای وب نامعتبر، مانند نمونهای که در مثال قبل نشان داده شد، در WebView
بهصورت متناقض مدیریت میشوند، بنابراین توصیه میکنیم به جای آن از یک URL با شکلدهی مناسب استفاده کنید. می توانید از یک طرح سفارشی یا یک URL HTTPS برای دامنه ای که سازمان شما کنترل می کند استفاده کنید.
به جای استفاده از یک رشته ساده در یک پیوند، مانند مثال قبلی، می توانید از یک طرح سفارشی مانند زیر استفاده کنید:
<a href="example-app:showProfile">Show Profile</a>
سپس می توانید این URL را در متد shouldOverrideUrlLoading()
خود به این صورت مدیریت کنید:
کاتلین
// 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 } }
جاوا
// 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; }
API shouldOverrideUrlLoading()
اساساً برای راهاندازی intent برای URLهای خاص در نظر گرفته شده است. هنگام اجرای آن، مطمئن شوید که برای URL هایی که WebView
کنترل می کند false
را برگردانید. با این حال، شما محدود به راه اندازی intent نیستید. میتوانید intent راهاندازی را با هر رفتار سفارشی در نمونههای کد قبلی جایگزین کنید.
پیمایش تاریخچه صفحات وب
وقتی WebView
شما بارگذاری URL را لغو می کند، به طور خودکار سابقه صفحات وب بازدید شده را جمع آوری می کند. با goBack()
و goForward()
می توانید در تاریخچه به عقب و جلو حرکت کنید.
برای مثال، موارد زیر نشان میدهد که چگونه Activity
شما میتواند از دکمه برگشت دستگاه برای پیمایش به عقب استفاده کند:
کاتلین
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) }
جاوا
@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); }
اگر برنامه از AndroidX AppCompat
1.6.0 و بالاتر استفاده می کند، می توانید قطعه قبلی را حتی بیشتر ساده کنید:
کاتلین
onBackPressedDispatcher.addCallback { // Check whether there's history. if (myWebView.canGoBack()) { myWebView.goBack() } }
جاوا
onBackPressedDispatcher.addCallback { // Check whether there's history. if (myWebView.canGoBack()) { myWebView.goBack(); } }
اگر تاریخچه صفحه وب برای بازدید کاربر وجود داشته باشد، متد canGoBack()
true را برمی گرداند. به همین ترتیب، میتوانید از canGoForward()
برای بررسی اینکه آیا تاریخچه فوروارد وجود دارد یا خیر استفاده کنید. اگر این بررسی را انجام ندهید، پس از اینکه کاربر به پایان تاریخچه رسید، goBack()
و goForward()
هیچ کاری انجام نمی دهند.
کنترل تغییرات پیکربندی دستگاه
در طول زمان اجرا، هنگامی که پیکربندی دستگاه تغییر می کند، تغییرات وضعیت فعالیت رخ می دهد، مانند زمانی که کاربران دستگاه را می چرخانند یا ویرایشگر روش ورودی (IME) را رد می کنند. این تغییرات باعث از بین رفتن اکتیویتی یک آبجکت WebView
و ایجاد یک اکتیویتی جدید می شود که همچنین یک آبجکت WebView
جدید ایجاد می کند که URL شیء تخریب شده را بارگذاری می کند. برای تغییر رفتار پیشفرض فعالیت خود، میتوانید نحوه مدیریت تغییرات orientation
در مانیفست خود را تغییر دهید. برای کسب اطلاعات بیشتر در مورد مدیریت تغییرات پیکربندی در زمان اجرا، Handle configuration changes را بخوانید.
ویندوز را مدیریت کنید
بهطور پیشفرض، درخواستها برای باز کردن پنجرههای جدید نادیده گرفته میشوند. این درست است چه آنها با جاوا اسکریپت باز شوند و چه توسط ویژگی هدف در یک پیوند. میتوانید WebChromeClient
خود را سفارشی کنید تا رفتار خود را برای باز کردن چندین پنجره ارائه دهد.
برای حفظ امنیت بیشتر برنامه خود، بهتر است از باز شدن پنجره های بازشو و جدید جلوگیری کنید. امنترین راه برای پیادهسازی این رفتار این است که "true"
به setSupportMultipleWindows()
منتقل کنید، اما متد onCreateWindow()
را که setSupportMultipleWindows()
به آن بستگی دارد لغو نکنید. این منطق از بارگذاری هر صفحه ای که target="_blank"
در لینک های خود استفاده می کند جلوگیری می کند.