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

פלטפורמת אנדרואיד מכילה מספר רב של ספריות ג'אווה משותפות שניתן לכלול כאופציה בנתיב הכיתה של אפליקציות עם התג <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) - היא גרסת הקומפילציה של ה-stubs. ה-libs המשמשים להידור זה אינם זהים לאלו שסופקו ל- java_sdk_library , מה שמבטיח שפרטי היישום לא ידלפו לתוך ה-API stubs.
    • אם אתה צריך ספריות נוספות כדי להדר את ה-stubs, השתמש במאפייני stub_only_libs ו- stub_only_static_libs כדי לספק אותם.

אם java_sdk_library נקראת " X ", והיא מורכבת כ- " X ", תמיד התייחס אליה כך ואל תשנה אותה. ה-build יבחר ספרייה מתאימה. כדי להבטיח שיש לך את הספרייה המתאימה ביותר, בדוק את השטבים שלך כדי לראות אם ה-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" משתמש ב-Public stubs, בעוד מודול המציין 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 שנמצאות בנתיב הכיתה בעת בניית 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