استخدام WebView
لتسليم تطبيق ويب
أو صفحة ويب كجزء من تطبيق عميل. الفئة WebView
هي
لفئة View
من نظام التشغيل Android تتيح
تعرض صفحات الويب كجزء من تخطيط نشاطك. ولا تشمل الحالة
الميزات المتوفرة في متصفح ويب مطور بالكامل، مثل عناصر التحكم في التنقل أو
شريط العناوين. كل ما يفعله WebView
هو عرض صفحة ويب تلقائيًا.
بإمكان "WebView
" مساعدتك في تقديم معلومات داخل تطبيقك قد تحتاج إلى
مثل اتفاقية المستخدم النهائي أو دليل المستخدم. داخل تطبيق Android،
يمكنك إنشاء Activity
يحتوي على
WebView
، بعد ذلك يمكنك استخدامه لعرض المستند الذي تمت استضافته على الإنترنت.
يمكن أن تساعد ميزة "WebView
" أيضًا عندما يوفّر تطبيقك بيانات للمستخدم الذي يتطلب.
بالإنترنت لاسترداد البيانات، مثل البريد الإلكتروني. في هذه الحالة، قد
أنه من الأسهل إنشاء WebView
في تطبيق Android الذي يعرض الويب
تحتوي على جميع بيانات المستخدمين، بدلاً من إجراء طلب عبر الشبكة،
تحليل البيانات وعرضها في تخطيط Android. بدلاً من ذلك، يمكنك تصميم
المُصممة للأجهزة التي تعمل بنظام التشغيل Android ثم تنفيذ
WebView
في تطبيق Android الذي يحمّل صفحة الويب
يوضِّح هذا المستند كيفية بدء استخدام WebView
وكيفية الربط.
JavaScript من صفحة الويب إلى الرمز من جهة العميل في تطبيق Android، وكيفية
التعامل مع التنقُّل في الصفحات، وكيفية إدارة النوافذ عند استخدام "WebView
".
استخدام WebView على الإصدارات السابقة من Android
لاستخدام أحدث ميزات "WebView
" بأمان على الجهاز، يستخدم تطبيقك
قيد التشغيل، أضف AndroidX
مكتبة Webkit. هذا صوت ثابت
مكتبة يمكنك إضافتها إلى تطبيقك لاستخدام واجهات برمجة تطبيقات android.webkit
غير
المتوفّرة لإصدارات النظام الأساسي السابقة.
أضِفه إلى ملف build.gradle
على النحو التالي:
Kotlin
dependencies { implementation("androidx.webkit:webkit:1.8.0") }
Groovy
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()
، باسم
كما هو موضح في المثال التالي:
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");
إضافة WebView في onCreate()
لإضافة WebView
إلى تطبيقك بطريقة onCreate()
الخاصة بالنشاط، استخدِم بدلاً من ذلك.
بشكل مشابه لما يلي:
Kotlin
val myWebView = WebView(activityContext) setContentView(myWebView)
Java
WebView myWebView = new WebView(activityContext); setContentView(myWebView);
بعد ذلك، حمِّل الصفحة:
Kotlin
myWebView.loadUrl("http://www.example.com")
Java
myWebView.loadUrl("https://www.example.com");
أو تحميل عنوان URL من سلسلة HTML:
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");
يجب أن يتصل تطبيقك بالإنترنت. للاتصال بالإنترنت، اطلب
إذن INTERNET
في
ملف البيان، كما هو موضح في المثال التالي:
<manifest ... > <uses-permission android:name="android.permission.INTERNET" /> ... </manifest>
يمكنك تخصيص WebView
من خلال تنفيذ أيّ من الإجراءات التالية:
- إتاحة استخدام وضع ملء الشاشة باستخدام
WebChromeClient
هذا الصف أيضًا عندما يحتاجWebView
إلى إذن لتغيير واجهة المستخدم للتطبيق المضيف، مثل إنشاء النوافذ أو إغلاقها أو إرسال مربعات حوار JavaScript إلى المستخدم. لمزيد من المعلومات حول تصحيح الأخطاء في هذا السياق، يُرجى الاطّلاع على تصحيح أخطاء الويب. التطبيقات. - معالجة الأحداث التي تؤثر في عرض المحتوى، مثل الأخطاء في النموذج
عمليات الإرسال أو التنقل باستخدام
WebViewClient
يمكنك أيضًا استخدام لهذه الفئة الفرعية لاعتراض تحميل عناوين URL. - تمكين جافا سكريبت عن طريق تعديل
WebSettings
- استخدام JavaScript للوصول إلى كائنات إطار عمل Android التي أدخلتها
إلى
WebView
.
استخدام JavaScript في WebView
إذا كانت صفحة الويب التي تريد تحميلها في WebView
تستخدم JavaScript، يجب
تفعيل JavaScript على جهاز WebView
. بعد تفعيل JavaScript، يمكنك
إنشاء واجهات بين رمز تطبيقك ورمز JavaScript
تفعيل JavaScript
تكون JavaScript غير مفعّلة تلقائيًا في WebView
. يمكنك تفعيله من خلال
تم إرفاق "WebSettings
" بجهاز WebView
. استرداد WebSettings
باستخدام
getSettings()
، ثم التفعيل
JavaScript مع
setJavaScriptEnabled()
اطّلِع على المثال التالي:
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
إمكانية الوصول إلى مجموعة متنوعة من الإعدادات الأخرى التي قد تجدها.
مفيدة. على سبيل المثال، إذا كنت تعمل على تطوير تطبيق ويب مصمّم
خصيصًا لـ WebView
في تطبيق Android، يمكنك بعد ذلك تحديد
سلسلة وكيل المستخدم مع
setUserAgentString()
,
ثم الاستعلام عن وكيل المستخدم المخصص في صفحة الويب الخاصة بك للتحقق من أن العميل
الذي يطلب صفحة الويب هو تطبيق Android.
ربط رمز JavaScript برمز Android
عند تطوير تطبيق ويب مصمّم خصيصًا لنظام WebView
في تطبيق Android، يمكنك إنشاء واجهات بين رمز JavaScript
رمز Android من جهة العميل. على سبيل المثال، يمكن لشفرة JavaScript استدعاء طريقة في
رمز Android لعرض Dialog
،
بدلاً من استخدام دالة alert()
في JavaScript.
لربط واجهة جديدة بين رمز JavaScript ورمز Android، اطلب
addJavascriptInterface()
،
تمريره مثيل فئة لربطه بلغة JavaScript واسم الواجهة
التي يمكن لـ JavaScript طلبها للوصول إلى الفئة.
على سبيل المثال، يمكنك تضمين الفئة التالية في تطبيق Android:
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(); } }
في هذا المثال، تتيح الفئة WebAppInterface
لصفحة الويب إنشاء
Toast
، باستخدام showToast()
.
يمكنك ربط هذا الصف بمحتوى JavaScript الذي يتم تشغيله في WebView
باستخدام
addJavascriptInterface()
، كما هو موضّح في المثال التالي:
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");
تؤدي هذه الخطوة إلى إنشاء واجهة باسم "Android
" لبرنامج JavaScript الذي يتم تشغيله في
WebView
في هذه المرحلة، يمكن لتطبيق الويب الوصول إلى
صف واحد (WebAppInterface
). على سبيل المثال، إليك بعض ترميز HTML وJavaScript الذي
ينشئ رسالة إشعار منبثق باستخدام الواجهة الجديدة عندما ينقر المستخدم على أحد الأزرار:
<input type="button" value="Say hello" onClick="showAndroidToast('Hello Android!')" /> <script type="text/javascript"> function showAndroidToast(toast) { Android.showToast(toast); } </script>
ولا حاجة إلى إعداد واجهة Android
من JavaScript. تشير رسالة الأشكال البيانية
WebView
يجعلها متاحة تلقائيًا لصفحتك على الويب. لذلك، عندما يبحث مستخدم
تنقر على الزر، تستخدم الدالة showAndroidToast()
الواجهة Android
لاستدعاء طريقة WebAppInterface.showToast()
.
التعامل مع التنقل في الصفحات
عندما ينقر المستخدم على رابط من صفحة ويب في WebView
، Android تلقائيًا
يبدأ تشغيل تطبيق يعالج عناوين URL. عادةً، يفتح متصفح الويب الافتراضي
من تحميل عنوان URL المقصود. ومع ذلك، يمكنك إلغاء هذا السلوك
WebView
لذلك يتم فتح الروابط في WebView
. يمكنك بعد ذلك السماح للمستخدم
التنقل للأمام وللخلف عبر سجل صفحات الويب الخاص بهم الذي يتم الاحتفاظ به
بواسطة WebView
.
لفتح الروابط التي نقر عليها المستخدم، قدِّم WebViewClient
لـ WebView
.
استخدام
setWebViewClient()
يتم تحميل جميع الروابط التي ينقر عليها المستخدم في WebView
. إذا كنت تريد مزيدًا من التحكم في
حيث يتم تحميل رابط تم النقر عليه، يمكنك إنشاء WebViewClient
خاصة بك تلغي
shouldOverrideUrlLoading()
. يفترض المثال التالي أن MyWebViewClient
هي فئة داخلية
من Activity
.
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; } }
بعد ذلك، يمكنك إنشاء مثيل من WebViewClient
الجديد في WebView
:
Kotlin
val myWebView: WebView = findViewById(R.id.webview) myWebView.webViewClient = MyWebViewClient()
Java
WebView myWebView = (WebView) findViewById(R.id.webview); myWebView.setWebViewClient(new MyWebViewClient());
عندما ينقر المستخدم على رابط ما، يستدعي النظام الآن
shouldOverrideUrlLoading()
التي تتحقّق ممّا إذا كان مضيف عنوان URL مطابقًا
مجال معين، كما هو موضح في المثال السابق. إذا كان يتطابق،
تعرض الطريقة القيمة false ولا تلغي تحميل عنوان URL. إنه يتيح
يُحمِّل WebView
عنوان URL كالمعتاد. وفي حال عدم تطابق مضيف عنوان URL، لن تظهر
تم إنشاء Intent
لإطلاق الإعدادات التلقائية
Activity
للتعامل مع عناوين URL، والذي يؤدي إلى متصفح الويب التلقائي للمستخدم.
التعامل مع عناوين URL المخصَّصة
يتم تطبيق القيود من قِبل WebView
عند طلب المراجع وحلّ الروابط.
التي تستخدم مخطط عنوان URL مخصصًا. على سبيل المثال، إذا قمت بتنفيذ استدعاءات مثل
shouldOverrideUrlLoading()
أو
shouldInterceptRequest()
,
ثم يستدعيها WebView
لعناوين URL الصالحة فقط.
على سبيل المثال، قد لا يتمكن WebView
من استدعاء طريقة shouldOverrideUrlLoading()
عن روابط مثل هذه:
<a href="showProfile">Show Profile</a>
تتم معالجة عناوين URL غير الصالحة، مثل العنوان الذي يظهر في المثال السابق.
على نحو غير متسق في WebView
، لذا ننصح باستخدام عنوان URL مكتوب بشكل صحيح بدلاً من ذلك.
يمكنك استخدام مخطط مخصّص أو عنوان URL يستخدم HTTPS لنطاق مؤسستك
والتحكم المستمر.
بدلاً من استخدام سلسلة بسيطة في رابط، كما في المثال السابق، يمكنك استخدام مخطط مخصّص، مثل ما يلي:
<a href="example-app:showProfile">Show Profile</a>
ويمكنك بعد ذلك التعامل مع عنوان URL هذا بطريقة shouldOverrideUrlLoading()
مثل
التالي:
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()
مصمَّمة في المقام الأول لأغراض إطلاق المنتجات.
لعناوين URL محددة عند تنفيذه، احرص على عرض false
لعناوين URL.
مؤشرات WebView
. ومع ذلك، فأنت لا تقتصر على نوايا إطلاق المنتجات. يمكنك
يستبدل أغراض الإطلاق بأي سلوك مخصص في الرمز السابق
العينات.
التنقل في سجلّ صفحات الويب
عندما يلغي WebView
تحميل عنوان URL، يتم تلقائيًا تجميع
سجل صفحات الويب التي تمت زيارتها. يمكنك الانتقال للخلف وللأمام من خلال
سجلّ مع goBack()
goForward()
على سبيل المثال، يوضّح ما يلي طريقة استخدام "Activity
" للجهاز Back
زر للانتقال للخلف:
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); }
إذا كان تطبيقك يستخدم الإصدار 1.6.0 من نظام التشغيل AndroidX AppCompat
أو الإصدارات الأحدث، يمكنك تبسيط الإجراء السابق.
مقتطفات أكثر:
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()
على "صواب" إذا كان هناك سجل صفحة ويب يمكن للمستخدم زيارته. وبالمثل،
يمكن استخدام canGoForward()
من أجل
للتحقق مما إذا كان هناك سجل إعادة توجيه. إذا لم تقم بإجراء هذا الفحص، فحينئذٍ
بعد وصول المستخدِم إلى نهاية السجلّ، يفعل goBack()
وgoForward()
لا شيء.
التعامل مع التغييرات على إعدادات الجهاز
أثناء بيئة التشغيل، تحدث تغييرات حالة النشاط عند ضبط الجهاز
التغييرات، مثل التغييرات التي تحدث عند تدوير الجهاز أو تجاهل أحد محرِّري أساليب الإدخال
(IME). تؤدي هذه التغييرات إلى تلف نشاط كائن WebView
و
إنشاء نشاط جديد، ما يؤدي أيضًا إلى إنشاء عنصر WebView
جديد يتم تحميله
عنوان URL الخاص بالعنصر المدمّر. لتعديل السلوك التلقائي لنشاطك، يمكنك
تغيير طريقة تعامله مع تغييرات orientation
في بيان التطبيق معرفة المزيد
حول التعامل مع تغييرات الضبط أثناء وقت التشغيل، يُرجى الاطّلاع على إعداد الاسم المعرِّف
التغييرات.
إدارة النوافذ
يتم تلقائيًا تجاهل طلبات فتح النوافذ الجديدة. هذا صحيح سواء قاموا
يتم فتحها بواسطة JavaScript أو من خلال السمة المستهدفة في رابط. يمكنك تخصيص
WebChromeClient
لتقديم سلوكك الخاص لفتح العديد من
.
للحفاظ على أمان تطبيقك، يُفضَّل منع ظهور النوافذ المنبثقة والنوافذ الجديدة
فتح. الطريقة الأكثر أمانًا لتنفيذ هذا السلوك هي تمرير "true"
إلى
setSupportMultipleWindows()
ولكن لا تتجاهل
onCreateWindow()
التي تعتمد عليها setSupportMultipleWindows()
. يمنع هذا المنطق أي
تستخدم target="_blank"
في الروابط الخاصة بها من التحميل.