הטמעת ספריית Java SDK

פלטפורמת Android מכילה מספר גדול של ספריות Java משותפות שאפשר לכלול באופן אופציונלי ב-classpath של אפליקציות עם תג <uses-library> בקובץ המניפסט של האפליקציה. קישור לאפליקציות כנגד הספריות האלה, לכן צריך להתייחס אליהן כמו לכל שאר ממשקי ה-API של Android מבחינת תאימות, בדיקת API ותמיכה בכלים. עם זאת, שימו לב ברוב הספריות אין את התכונות האלה.

סוג המודול java_sdk_library עוזר בניהול ספריות מהסוג הזה. יצרני מכשירים יכולים להשתמש במנגנון הזה משותפות ספריות Java, כדי לשמור על תאימות לאחור עבור ממשקי ה-API שלהן. אם יצרני המכשירים משתמשים בספריות Java משותפות משלהם דרך התג <uses-library> במקום הנתיב של סיווג האתחול, java_sdk_library יכול לאמת שספריות Java האלה יציב API.

ב-java_sdk_library מוטמעים ממשקי API אופציונליים של SDK לשימוש על ידי באפליקציות. ספריות שהוטמעו באמצעות java_sdk_library ב- קובץ build (Android.bp) מבצע את הפעולות הבאות:

  • ספריות ה-stubs נוצרות כדי לכלול את stubs, stubs.system ו-stubs.test. האלה ספריות stubs נוצרות על ידי זיהוי ה-@hide, @SystemApi ו-@TestApi הערות.
  • java_sdk_library מנהל את קובצי המפרט של ה-API (למשל current.txt) בספריית משנה של API. הקבצים האלה נבדקים מול הקוד העדכני ביותר כדי לוודא שהם הגרסאות הנוכחיות. אם לא, תקבלו הודעת שגיאה שמסביר איך לעדכן אותם. בדוק ידנית את כל שינויי העדכון ל- ולוודא שהן תואמות לציפיות שלכם.

    כדי לעדכן את כל ממשקי ה-API, צריך להשתמש ב-m update-api. כדי לוודא שה-API עדכני, להשתמש ב-m checkapi.
  • קובצי המפרט של ה-API נבדקים מול הקבצים העדכניים ביותר שפורסמו בגרסאות Android כדי לוודא שה-API תואם לאחור. עם גרסאות קודמות. המודולים של java_sdk_library שסופקו כחלק מ-AOSP, הטמיעו את הגרסאות הקודמות שלהם prebuilts/sdk/<latest number>.
  • בנוגע לבדיקות הקבצים של מפרט ה-API, אפשר לבצע את הפעולות הבאות: אחד משלושת הדברים הבאים:
    • צריך להמתין לבדיקות. (לא לעשות דבר).
    • כדי להשבית את הבדיקות, צריך להוסיף את הפרטים הבאים אל java_sdk_library:
      unsafe_ignore_missing_latest_api: true,
    • צריך לספק ממשקי API ריקים למודולים חדשים של java_sdk_library על ידי יצירת קובצי טקסט ריקים בשם module_name.txt הספרייה version/scope/api.
  • אם ספריית ההטמעה של סביבת זמן הריצה מותקנת, קובץ XML נוצר ומותקן.

איך פועלת Java_sdk_library

java_sdk_library בשם X יוצר את הערך הבא:

  1. שני עותקים של ספריית ההטמעה: ספרייה אחת בשם X ועוד אחד בשם X.impl. הספרייה X הותקנה במכשיר. הספרייה X.impl זמינה רק אם יש בה גישה מפורשת את ספריית ההטמעה נדרשת למודולים אחרים, כמו בדיקה. חשוב לדעת שנדרשת גישה מפורשת לעיתים רחוקות.
  2. אפשר להפעיל ולהשבית היקפי הרשאות כדי להתאים אישית את הגישה. (דומה ל-Java מגבילי גישה למילות מפתח, היקף ציבורי מספק מגוון רחב של גישה; A היקף הבדיקה מכיל ממשקי API שמשמשים לבדיקה בלבד). עבור כל היקף פעיל, יוצרת את הדברים הבאים:
    • מודול מקור stubs (מסוג מודול droidstubs) - צורך את מקור ההטמעה ומפיקה פלט של קבוצה של מקורות stub יחד עם את קובץ המפרט של ה-API.
    • ספריית stubs (מסוג המודול java_library) - היא של ה-stubs. הליבים ששימשו להרכבת הם לא זהים לאלה שסופקו לרכיב java_sdk_library, כדי להבטיח פרטי ההטמעה לא דולפים ל-stubs של ה-API.
    • אם יש צורך בספריות נוספות כדי להדר את ה-stubs, אפשר להשתמש stub_only_libs ו-stub_only_static_libs כדי לספק אותם.

אם java_sdk_library נקרא "X", שמאוגדים בתור 'X', תמיד יתייחסו אליו ככה ולא תשנו את זה. ה-build יבחר ספרייה מתאימה. כדי לוודא שיש לך את הספרייה המתאימה ביותר, בדקו את השקפים שלכם כדי לראות אם ה-build שגיאות. מבצעים את התיקונים הנחוצים לפי ההנחיות האלה:

  • ודאו שיש לכם ספרייה מתאימה על ידי בדיקת שורת הפקודה כדי לקבוע את ההיקף שלה:
    • ההיקף רחב מדי: לספרייה שתלויה נדרש היקף מסוים של ממשקי API. אבל תראו בספרייה ממשקי API שלא נכללים בהיקף הזה, ממשקי ה-API של המערכת שכלולים בממשקי ה-API הציבוריים.
    • ההיקף מצומצם מדי: לספרייה התלויה אין גישה לכל של הספריות הנדרשות. לדוגמה, הספרייה התלויה צריכה להשתמש ב- אבל הוא מקבל את ה-API הציבורי במקום זאת. בדרך כלל התוצאה שגיאת הידור (compilation) כי חסרים ממשקי API נדרשים.
  • כדי לתקן את הספרייה, צריך לבצע רק אחת מהפעולות הבאות:
    • צריך לשנות את sdk_version כדי לבחור את הגרסה הדרושה. או
    • צריך לציין במפורש את הספרייה המתאימה, למשל <X>.stubs. או <X>.stubs.system.

שימוש ב-Java_sdk_library X

נעשה שימוש בספריית ההטמעה X כאשר יש הפניה אליה מ- apex.java_libs. עם זאת, עקב מגבלת סונג, כשהספרייה קיימת הפניה אל X ממודול אחר של java_sdk_library באותה ספריית APEX, X.impl באופן מפורש חייב להיות בשימוש, לא ספרייה X.

כשיש הפניה ל-java_sdk_library ממקום אחר, ה-stub הספרייה בשימוש. ספריית ה-stubs נבחרת בהתאם הגדרת המאפיין sdk_version במודול. לדוגמה, מודול מציין ש-sdk_version: "current" משתמש בשאר הרכיבים הציבוריים, המודול שמציין את sdk_version: "system_current" משתמש ב-stubs של מערכת. אם לא ניתן למצוא התאמה מדויקת, ספריית ה-stub הקרובה ביותר מקבלת בשימוש. java_sdk_library שמספק רק API ציבורי מספק את ההלבנות הציבוריות לכולם.

יצירת תהליך עבודה באמצעות ספריית Java SDK
איור 1. יצירת תהליך עבודה באמצעות ספריית Java SDK

דוגמאות ומקורות

הנכסים srcs ו-api_packages חייבים נמצאים בjava_sdk_library.

java_sdk_library {
        name: "com.android.future.usb.accessory",
        srcs: ["src/**/*.java"],
        api_packages: ["com.android.future.usb"],
    }

AOSP ממליץ (אבל לא דורש) שjava_sdk_library חדש מכונות הפעלה מפורשות של היקפי ה-API שבהם הם רוצים להשתמש. אפשר גם (אופציונלי) אפשר להעביר מכונות java_sdk_library קיימות אל להפעיל במפורש את היקפי ה-API שבהם הם ישתמשו:

java_sdk_library {
         name: "lib",
         public: {
           enabled: true,
         },
         system: {
           enabled: true,
         },
         …
    }

כדי להגדיר את הספרייה impl שמשמשת את סביבת זמן הריצה, צריך להשתמש בכל מאפייני java_library הרגילים, כמו hostdex, compile_dex ו-errorprone.

java_sdk_library {
        name: "android.test.base",

        srcs: ["src/**/*.java"],

        errorprone: {
          javacflags: ["-Xep:DepAnn:ERROR"],
        },

        hostdex: true,

        api_packages: [
            "android.test",
            "android.test.suitebuilder.annotation",
            "com.android.internal.util",
            "junit.framework",
        ],

        compile_dex: true,
    }

כדי להגדיר ספריות stubs, צריך להשתמש במאפיינים הבאים:

  • merge_annotations_dirs וגם merge_inclusion_annotations_dirs
  • api_srcs: רשימה של קובצי מקור אופציונליים שהם חלק של ה-API אבל לא חלק מספריית זמן הריצה.
  • stubs_only_libs: הרשימה של ספריות Java שנמצאות בזמן בניית ה-stubs.
  • hidden_api_packages: רשימה של שמות חבילות שחייבים להיות מוסתרים מה-API.
  • droiddoc_options: ארגומנט נוסף עבור מטאלווה.
  • droiddoc_option_files: פירוט הקבצים שאפשר להפנות אליהם מתוך droiddoc_options באמצעות $(location <label>), כאשר <file> הוא רשומה ברשימה.
  • annotations_enabled.

הjava_sdk_library הוא java_library, אבל הוא לא המודול droidstubs ולכן הוא לא תומך בכל droidstubs נכסים. הדוגמה הבאה נלקחה גרסת build של ספרייה ב-android.test.mock חדש.

java_sdk_library {
        name: "android.test.mock",

        srcs: [":android-test-mock-sources"],
        api_srcs: [
            // Note: The following aren’t APIs of this library. Only APIs under the
            // android.test.mock package are taken. These do provide private APIs
            // to which android.test.mock APIs reference. These classes are present
            // in source code form to access necessary comments that disappear when
            // the classes are compiled into a Jar library.
            ":framework-core-sources-for-test-mock",
            ":framework_native_aidl",
        ],

        libs: [
            "framework",
            "framework-annotations-lib",
            "app-compat-annotations",
            "Unsupportedappusage",
        ],

        api_packages: [
            "android.test.mock",
        ],
        permitted_packages: [
            "android.test.mock",
        ],
        compile_dex: true,
        default_to_stubs: true,
    }

שמירה על תאימות לאחור

מערכת ה-build בודקת אם ממשקי ה-API שמרו לאחור תאימות על ידי השוואה בין קובצי ה-API האחרונים קובצי API בזמן ה-build. הקוד java_sdk_library מבצע את בדיקת תאימות באמצעות המידע שסופק על ידי prebuilt_apis. כל הספריות שפותחו באמצעות java_sdk_library חייבות להכיל קובצי API בגרסה האחרונה של api_dirs בprebuilt_apis. לאחר פרסום הגרסה, ה-API מציג רשימה של קבצים ו-stubs אפשר להשיג ספריות באמצעות build שונה באמצעות PRODUCT=sdk_phone_armv7-sdk.

המאפיין api_dirs הוא רשימה של ספריות של גרסאות API ב-prebuilt_apis. הספריות של גרסת ה-API חייבות להיות נמצאים ברמת הספרייה Android.bp.

prebuilt_apis {
       name: "foo",
       api_dirs: [
           "1",
           "2",
             ....
           "30",
           "current",
       ],
    }

מגדירים את הספריות עם version/scope/api/ בתוך הספרייה המובנית מראש. version שתואם לרמת ה-API ו-scope מגדיר האם הספרייה ציבורית, מערכת או בדיקה.

  • version/scope שמכיל ספריות Java.
  • version/scope/api מכיל API .txt קבצים. יצירת קובצי טקסט ריקים בשם module_name.txt וmodule_name-removed.txt כאן.
     ├── 30
          │   ├── public
          │   │   ├── api
          │   │   │   ├── android.test.mock-removed.txt
          │   │   │   └── android.test.mock.txt
          │   │   └── android.test.mock.jar
          │   ├── system
          │   │   ├── api
          │   │   │   ├── android.test.mock-removed.txt
          │   │   │   └── android.test.mock.txt
          │   │   └── android.test.mock.jar
          │   └── test
          │       ├── api
          │       │   ├── android.test.mock-removed.txt
          │       │   └── android.test.mock.txt
          │       └── android.test.mock.jar
          └── Android.bp