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

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

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

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

  • ספריות ה-stubs נוצרות כדי לכלול stubs , stubs.system ו- stubs.test . ספריות סתימות אלו נוצרות על ידי זיהוי @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 מילות מפתח, היקף ציבורי מספק מגוון רחב של גישה; היקף בדיקה מכיל ממשקי API המשמשים רק בבדיקה.) עבור כל היקף מופעל הספרייה יוצרת את הדברים הבאים:
    • מודול מקור stubs (מטיפוס מודול droidstubs ) - צורך את מקור היישום ומוציא קבוצה של מקורות stubs יחד עם קובץ מפרט ה-API.
    • ספריית stubs (מסוג java_library module) - היא גרסת הקומפילציה של הסטאבים. ה-libs המשמשים להידור זה אינם זהים לאלו שסופקו ל- java_sdk_library , מה שמבטיח שפרטי היישום לא ידלפו לתוך ה-API stubs.
    • אם אתה צריך ספריות נוספות כדי להדר את ה-stubs, השתמש stub_only_libs ו- stub_only_static_libs כדי לספק אותם.

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

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

שימוש ב-java_sdk_library X

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

כאשר הפנייה ל- java_sdk_library ממקום אחר, נעשה שימוש בספריית stubs. ספריית ה-stubs נבחרה בהתאם להגדרת המאפיין sdk_version של המודול התלוי. לדוגמה, מודול שמציין את sdk_version: "current" משתמש בסטאב הציבורי, בעוד שמודול שמציין את sdk_version: "system_current" משתמש ב-Stubs של המערכת. אם לא ניתן למצוא התאמה מדוייקת, ספריית השבבים הקרובה ביותר תשתמש. 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,
    }

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

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

ה- java_sdk_library היא java_library , אך היא אינה מודול droidstubs ולכן אינו תומך בכל מאפייני ה- droidstubs . הדוגמה הבאה נלקחה מקובץ הבנייה של ספריית 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,
    }

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

מערכת הבנייה בודקת אם ממשקי ה-API שמרו על תאימות לאחור על ידי השוואת קבצי ה-API העדכניים ביותר לקבצי ה-API שנוצרו בזמן הבנייה. ה- java_sdk_library מבצע את בדיקת התאימות באמצעות המידע המסופק על ידי prebuilt_apis . כל הספריות שנבנו עם java_sdk_library חייבות להיות קבצי API בגרסה העדכנית ביותר של api_dirs ב- prebuilt_apis . כאשר אתה משחרר את הגרסה, ה-API מציג רשימה של קבצים וספריות תווים ניתן להשיג עם מבנה dist עם 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/ תחת ספריית prebuilts. version מתאימה לרמת ה-API scope מגדיר אם הספרייה היא ציבורית, מערכת או בדיקה.

  • version / scope מכיל ספריות Java.
  • version / scope /api מכיל קבצי .txt של API. צור כאן קבצי טקסט ריקים בשם 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