אפליקציות WebView למפתחי אתרים

תאריך פרסום: 28 בפברואר 2014

איך יוצרים פרויקט Android חדש, מוסיפים Webview, טוענים כתובת URL מרוחקת וטוענים דף HTML מקומי.

במדריך הזה אנחנו יוצאים מנקודת הנחה שאתם מפתחים עם ניסיון מוגבל בסביבת הפיתוח של Android, או שאין לכם ניסיון בכלל, אבל יש לכם ניסיון מסוים ב-Kotlin. אם אתם כבר מכירים את התכנות ל-Android, מומלץ לקרוא את המאמר פיתוח אפליקציות אינטרנט ב-WebView באתר למפתחים של Android.

התקנת Android Studio

במדריך הזה נעשה שימוש ב-Android Studio, סביבת הפיתוח המשולבת (IDE) ל-Android לצורכי עיצוב ופיתוח.

יצירת פרויקט חדש ל-Android

לאחר ההתקנה של Android Studio, אשף ההגדרה יופעל.

כדי ליצור פרויקט חדש:

  1. לוחצים על New Project.
  2. לוחצים על התבנית Empty Activity כדי לבחור אותה לפרויקט. התבניות יוצרות את המבנה של הפרויקט ואת הקבצים הנדרשים ל-Android Studio כדי ליצור את הפרויקט.
  3. לוחצים על הבא כדי לפתוח את תיבת הדו-שיח New Project (פרויקט חדש).
  4. מגדירים את הפרויקט. מזינים את שם האפליקציה, שם החבילה ו-SDKs היעד. לאחר מכן לוחצים על הבא.
  5. מגדירים את גרסת ה-SDK המינימלית הנדרשת ל-API 24: Android 7.0‏ (Nougat).
  6. לוחצים על סיום.

הפרויקט החדש ייפתח ב-Android Studio.

מבנה הפרויקט

בפרויקט הראשוני שנוצר על ידי Android Studio יש קוד לדוגמה להגדרת האפליקציה. כמה מהתיקיות הנפוצות יותר לייבוא כוללות:

  • src/main/java. קוד מקור של Java ל-Android.
  • src/main/res. משאבים שבהם האפליקציה משתמשת.
  • src/main/res/drawable. משאבי תמונות שבהם האפליקציה משתמשת.
  • קובצי פריסה מסוג src/main/res/xml. XML שמגדירים את המבנה של רכיבי ממשק המשתמש.
  • src/main/res/values. מאפיינים, מחרוזות וערכים אחרים שאולי לא תרצו להטמיע בקוד האפליקציה.
  • src/main/AndroidManifest.xml. קובץ המניפסט מגדיר את התוכן הכלול באפליקציה, כמו פעילויות, הרשאות ועיצובים.

הוספת WebView

בשלב הבא, מוסיפים WebView לפריסה של הפעילות הראשית.

  1. פותחים את הקובץ activity_main.xml בספרייה src/main/res/xml, אם הוא עדיין לא פתוח. (יכול להיות שיופיע גם קובץ fragment_main.xml. אפשר להתעלם מהבקשה הזו, כי היא לא נדרשת למדריך הזה).

    בוחרים בכרטיסייה Text (טקסט) בתחתית עורך activity_main.xml כדי להציג את ה-markup של ה-XML.

    הקובץ הזה מגדיר את הפריסה של הפעילות הראשית, ובחלוניות Preview מוצגת תצוגה מקדימה של הפעילות. הפריסה פעילות ריקה לא כוללת רכיבי צאצאים. תצטרכו להוסיף את WebView.

  2. בחלונית ה-XML, מסירים את הקו נטוי הסגור בעצמו בסוף האלמנט FrameLayout, ומוסיפים את האלמנט <WebView> ותג סגירה חדש, כפי שמוצג:

    <FrameLayout xmlns:android="https://schemas.android.com/apk/res/android"
        xmlns:tools="https://schemas.android.com/tools"
        android:id="@+id/container"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MainActivity">
        tools:ignore="MergeRootFrame">
    
        <WebView
          android:id="@+id/activity_main_webview"
          android:layout_width="match_parent"
          android:layout_height="match_parent" />
    </FrameLayout>
    
  3. כדי להשתמש ב-WebView, צריך להפנות אליו ב-Activity. פותחים את קובץ המקור של Java לפעילות הראשית, MainActivity.java, בספרייה src/main/java/<PackageName>.

    מוסיפים את השורות שמודגשות.

    public class MainActivity extends Activity {
    
        private WebView mWebView;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            mWebView = (WebView) findViewById(R.id.activity_main_webview);
    

    הקוד הקיים בשיטה onCreate מחבר את הפעילות לפריסה. השורות שנוספו יוצרות משתנה חבר חדש, mWebView, כדי להפנות לתצוגת האינטרנט.

    מסירים את הקוד הבא:

    if (savedInstanceState == null) {
      getSupportFragmentManager().beginTransaction()
        .add(R.id.container, new PlaceholderFragment())
        .commit();
    }
    

    רכיב WebView מזוהה לפי מזהה המשאב, שמופיע בשורה הבאה בקובץ הפריסה:

    android:id="@+id/activity_main_webview"
    

    אחרי הוספת הקוד, יופיעו כמה הודעות אזהרה בשוליים של העורך. הסיבה לכך היא שלא ייבאת את הכיתות המתאימות ל-WebView. למרבה המזל, אפשר להיעזר ב-Android Studio כדי למלא את הכיתות החסרות. הדרך הקלה ביותר לעשות זאת היא ללחוץ על שם הכיתה הלא מוכרת ולהעביר את העכבר מעליו, ולהמתין עד שיופיע מודול עם 'תיקון מהיר' – במקרה הזה, הוספת הצהרת import לכיתה WebView.

    מקישים על Alt + Enter (Option + Enter ב-Mac) כדי לאשר את התיקון המהיר.

    עכשיו, כשיש לכם רכיב WebView, תוכלו להמשיך להגדיר אותו ולטעון תוכן אינטרנט מעניין.

הפוך JavaScript לפעיל

כברירת מחדל, WebView לא מאפשר JavaScript. כדי להריץ אפליקציית אינטרנט ב-WebView, צריך להפעיל את JavaScript באופן מפורש על ידי הוספת השורות הבאות ל-method‏ onCreate:

// Enable Javascript
WebSettings webSettings = mWebView.getSettings();
webSettings.setJavaScriptEnabled(true);

טעינת כתובת URL מרוחקת

אם אתם רוצים לטעון נתונים מכתובת URL מרוחקת, לאפליקציה צריכה להיות הרשאה לגשת לאינטרנט. צריך להוסיף את ההרשאה הזו בקובץ המניפסט של האפליקציה.

  1. פותחים את הקובץ AndroidManifest.xml בספרייה src/res. מוסיפים את השורה המודגשת לפני תג </manifest> הסוגר.

    <?xml version="1.0" encoding="utf-8"?>
    <manifest ...>
    ...
     
      </application>
      <uses-permission android:name="android.permission.INTERNET" />
    </manifest>
    
  2. השלב הבא הוא להפעיל את השיטה loadUrl ב-webview. מוסיפים את השורה הבאה בסוף השיטה onCreate.

    mWebView.loadUrl("[https://beta.html5test.com/][8]");
    

    עכשיו ננסה להריץ את הפרויקט. אם אין לכם מכשיר זמין, תוכלו ליצור אמולטור (AVD או מכשיר וירטואלי של Android) על ידי מעבר אל כלים > Android > AVD Manager.

ניווט באמצעות הידית

אפשר לנסות לשנות את כתובת ה-URL שאתם טוענים ל-https://www.css-tricks.com/ ולהריץ מחדש את האפליקציה. תבחינו במשהו מוזר.

אם תפעילו עכשיו את האפליקציה עם אתר עם הפניה אוטומטית כמו css-tricks.com, האפליקציה תפתח את האתר בדפדפן במכשיר, ולא ב-WebView – וכנראה שזה לא מה שציפיתם. הסיבה לכך היא האופן שבו WebView מטפל באירועי ניווט.

זהו רצף האירועים:

  1. WebView מנסה לטעון את כתובת ה-URL המקורית מהשרת המרוחק, ומקבל הפניה לכתובת URL חדשה.
  2. רכיב ה-WebView בודק אם המערכת יכולה לטפל בכוונה להצגה של כתובת ה-URL. אם כן, המערכת מטפלת בניווט בכתובת ה-URL. אחרת, רכיב ה-WebView מנווט באופן פנימי (לדוגמה, אם למשתמש אין דפדפן מותקן במכשיר).
  3. המערכת בוחרת את האפליקציה המועדפת של המשתמש לטיפול בסכימת כתובת ה-URL https://, כלומר הדפדפן שמוגדר כברירת מחדל של המשתמש. אם מותקנים במחשב יותר מדפדפן אחד, יכול להיות שתופיע תיבת דו-שיח בשלב הזה.

אם אתם משתמשים ב-WebView באפליקציה ל-Android כדי להציג תוכן (לדוגמה, דף עזרה), יכול להיות שזה בדיוק מה שאתם רוצים לעשות. עם זאת, באפליקציות מתוחכמות יותר, כדאי לטפל בעצמכם בקישורים לניווט.

כדי לטפל בניווט בתוך WebView, צריך לשנות את WebViewClient של WebView, שמטפל באירועים שונים שנוצרים על ידי WebView. אפשר להשתמש בה כדי לקבוע איך WebView יטפל בלחיצות על קישורים ובהפניות אוטומטיות לדפים.

בהטמעה שמוגדרת כברירת מחדל של WebViewClient, כל כתובת URL נפתחת ב-WebView:

// Force links and redirects to open in the WebView instead of in a browser
mWebView.setWebViewClient(new WebViewClient());

זהו צעד טוב קדימה, אבל מה קורה אם רוצים לטפל בקישורים לאתר בלבד, ולפתוח כתובות URL אחרות בדפדפן?

כדי לעשות זאת, צריך להרחיב את המחלקה WebViewClient ולהטמיע את השיטה shouldOverrideUrlLoading. המערכת קוראת לשיטה הזו בכל פעם ש-WebView מנסה לנווט לכתובת URL אחרת. אם הפונקציה מחזירה את הערך false, רכיב ה-WebView פותח את כתובת ה-URL בעצמו. (הטמעת ברירת המחדל תמיד מחזירה את הערך false, ולכן היא פועלת בדוגמה הקודמת).

יצירת כיתה חדשה:

  1. לוחצים לחיצה ימנית על שם החבילה של האפליקציה ובוחרים באפשרות New‏ > Java Class.
  2. מזינים את MyAppWebViewClient בתור שם הכיתה ולוחצים על OK.
  3. בקובץ MyAppWebViewClient.java החדש, מוסיפים את הקוד הבא (השינויים מודגשים):

    public class MyAppWebViewClient extends WebViewClient {
      @Override
      public boolean shouldOverrideUrlLoading(WebView view, String url) {
        if(Uri.parse(url).getHost().endsWith("css-tricks.com")) {
          return false;
        }
                   
        Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
        view.getContext().startActivity(intent);
        return true;
      }
    }
    

    הקוד החדש מגדיר את MyAppWebViewClient כסוג משנה של WebViewClient ומטמיע את השיטה shouldOverrideUrlLoading.

    השיטה shouldOverrideUrlLoading נקראת בכל פעם ש-WebView עומד לטעון כתובת URL. ההטמעה הזו בודקת אם מופיעה המחרוזת 'css-tricks.com' בסוף שם המארח של כתובת ה-URL. אם המחרוזת קיימת, השיטה מחזירה את הערך false, שמורה לפלטפורמה לא לשנות את כתובת ה-URL, אלא לטעון אותה ב-WebView.

    בכל שם מארח אחר, השיטה שולחת בקשה למערכת לפתוח את כתובת ה-URL. כדי לעשות זאת, המערכת יוצרת Intent חדש של Android ומשתמשת בו כדי להפעיל פעילות חדשה. החזרת הערך true בסוף השיטה מונעת את הטעינה של כתובת ה-URL ב-WebView.

  4. כדי להשתמש ב-WebViewClient המותאם אישית החדש, מוסיפים את השורות הבאות לכיתה MainActivity:

    // Stop local links and redirects from opening in browser instead of WebView
    mWebView.setWebViewClient(new MyAppWebViewClient());
    

    עכשיו, משתמשים יכולים ללחוץ על כל אחד מהקישורים של CSS Tricks ולהישאר באפליקציה, אבל קישורים לאתרים חיצוניים נפתחים בדפדפן.

טיפול בלחצן 'הקודם' ב-Android

כשמתחילים להתנסות ולנווט במאמרים של CSS Tricks, לחיצה על לחצן החזרה לאחור ב-Android תגרום ליציאה מהאפליקציה.

השיטה canGoBack ב-WebView מאפשרת לדעת אם יש משהו בסטאק הדפים שאפשר להוציא. כדי לזהות לחיצה על לחצן החזרה אחורה ולהחליט אם לחזור אחורה בהיסטוריה של WebView או לאפשר לפלטפורמה לקבוע את ההתנהגות הנכונה, מוסיפים את השיטה onBackPressed() ל-MainActivity:

public class MainActivity extends Activity {

 private WebView mWebView;

 @Override
 protected void onCreate(Bundle savedInstanceState) {
     ...
 }

    @Override
    public void onBackPressed() {
      if(mWebView.canGoBack()) {
        mWebView.goBack();
      } else {
        super.onBackPressed();
      }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
       ...
    }
}

טעינת HTML ממערכת הקבצים

אחד היתרונות הגדולים של שימוש ב-WebView באפליקציה שניתן להתקין הוא שאפשר לאחסן נכסים באפליקציה. כך האפליקציה יכולה לפעול במצב אופליין ומשך הטעינה קצר יותר, כי רכיב ה-WebView יכול לאחזר נכסים ישירות ממערכת הקבצים המקומית.

כדי לאחסן קבצים באופן מקומי, כולל קובצי HTML,‏ JavaScript ו-CSS, שומרים אותם בספריית הנכסים. זוהי ספרייה שמורה שבה Android משתמשת לקבצים גולמיים. לאפליקציה צריכה להיות גישה לספרייה הזו, כי יכול להיות שהיא תצטרך למזער או לדחוס קבצים מסוימים.

  1. יוצרים את הספרייה assets/www בקטע main (src/main/assets/www).

    • מומלץ לשמור את קובצי האינטרנט בספריית משנה של /assets.
  2. מעלים את כל הקבצים לספרייה.

  3. טוענים את הקובץ המתאים:

    mWebView.loadUrl("file:///android_asset/www/index.html");
    
  4. מעדכנים את השיטה shouldOverrideUrlLoading כדי לפתוח דפדפן לדפים לא מקומיים:

    public class MyAppWebViewClient extends WebViewClient {
      @Override
      public boolean shouldOverrideUrlLoading(WebView view, String url) {
        if(Uri.parse(url).getHost().length() == 0) {
          return false;
        }
    
        Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
        view.getContext().startActivity(intent);
        return true;
      }
    }
    

עכשיו אתם מוכנים ליצור אפליקציית WebView נהדרת.

טיפים לשיפור התצוגה החזותית מופיעים במאמר ממשק משתמש באיכות פיקסלים מושלמת ב-WebView.

אם תיתקלו בבעיות, תוכלו להיעזר בכלי הפיתוח של Chrome. במאמר ניפוי באגים מרחוק ב-Android מוסבר איך מתחילים.