פלטפורמת Android מכילה מספר גדול של ספריות Java משותפות שאפשר לכלול ב-classpath של אפליקציות באמצעות התג <uses-library>
במניפסט של האפליקציה. אפליקציות מקשרות לספריות האלה, לכן צריך להתייחס אליהן כמו לשאר Android API מבחינת תאימות, בדיקת API ותמיכה בכלים. עם זאת, חשוב לזכור שרוב הספריות לא כוללות את התכונות האלה.
סוג המודול java_sdk_library
עוזר לנהל ספריות מהסוג הזה. יצרני המכשירים יכולים להשתמש במנגנון הזה בספריות Java המשותפות שלהם, כדי לשמור על תאימות לאחור לממשקי ה-API שלהם.
אם יצרני המכשירים משתמשים בספריות Java משותפות משלהם דרך התג <uses-library>
במקום נתיב bootclass, אפשר להשתמש ב-java_sdk_library
כדי לוודא שספריות ה-Java האלה יציבות מבחינת ה-API.
ב-java_sdk_library
מוטמעים ממשקי API אופציונליים של SDK לשימוש באפליקציות. ספריות שמוטמעות באמצעות java_sdk_library
בקובץ ה-build (Android.bp
) מבצעות את הפעולות הבאות:
- ספריות הסטאבים נוצרות כך שיכללו את
stubs
,stubs.system
ו-stubs.test
. ספריות ה-stubs נוצרות על ידי זיהוי ההערות@hide
,@SystemApi
ו-@TestApi
. - קובצי המפרט של ה-API (כמו
current.txt
) מנוהלים על ידיjava_sdk_library
בתיקיית משנה של ה-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
יוצר את הפריטים הבאים:
- שני עותקים של ספריית ההטמעה: ספרייה אחת שנקראת
X
וספרייה אחרת שנקראתX.impl
. ספרייתX
מותקנת במכשיר. הספרייהX.impl
נמצאת רק אם מודולים אחרים זקוקים לגישה מפורשת לספריית ההטמעה, למשל לצורך בדיקה. חשוב לזכור שנדיר מאוד שנדרשת גישה מפורשת. - אפשר להפעיל ולהשבית היקפים כדי להתאים אישית את הגישה. (בדומה למגבילי הגישה של מילות מפתח ב-Java, היקף גלוי לכולם מספק מגוון רחב של הרשאות גישה, והיקף בדיקה מכיל ממשקי API שמשמשים רק לצורכי בדיקה). לכל היקף מופעל, הספרייה יוצרת את הפריטים הבאים:
- מודול מקור של stubs (מסוג מודול
droidstubs
) – צורך את מקור ההטמעה ומפיק קבוצה של מקורות stubs יחד עם קובץ המפרט של ה-API. - ספריית stubs (מסוג מודול
java_library
) – זוהי הגרסה המתומצתת של ה-stubs. הספריות ששימשו להדרכה הזו הן לא אותן ספריות שסופקו ל-java_sdk_library
, וכך מוודאים שפרטי ההטמעה לא דולפים לסטאבים של ה-API. - אם אתם זקוקים לספריות נוספות כדי לקמפל את הסטאבים, תוכלו להשתמש במאפיינים
stub_only_libs
ו-stub_only_static_libs
כדי לספק אותן.
אם java_sdk_library
נקרא X
, והוא עובר הידור כ-X
, תמיד צריך להתייחס אליו כך ולא לשנות אותו. ה-build יבחר ספרייה מתאימה. כדי לוודא שיש לכם את הספרייה המתאימה ביותר, בודקים את הסטאבים כדי לראות אם ה-build כלל שגיאות. מבצעים את התיקונים הנדרשים לפי ההנחיות הבאות:
- כדי לוודא שיש לכם ספרייה מתאימה, בודקים את שורת הפקודה ומעיינים בסטאבים שמפורטים בה כדי לקבוע את ההיקף:
- ההיקף רחב מדי: לספרייה התלויה נדרש היקף מסוים של ממשקי API. עם זאת, בספרייה יש ממשקי API שאינם נכללים בהיקף הזה, כמו ממשקי API של מערכת שכלולים בממשקי ה-API הציבוריים.
- ההיקף מצומצם מדי: לספרייה התלויה אין גישה לכל הספריות הנדרשות. לדוגמה, הספרייה התלויה צריכה להשתמש ב-API המערכת, אבל במקום זאת היא מקבלת את ה-API הציבורי. בדרך כלל התוצאה היא שגיאת הידור (compilation) כי ממשקי ה-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"
משתמש ב-stubs הציבוריים, ואילו מודול שמציין את הערך sdk_version: "system_current"
משתמש ב-stubs המערכתיים. אם לא ניתן למצוא התאמה מדויקת, המערכת משתמשת בספריית ה-stub הקרובה ביותר. java_sdk_library
שמספק רק ממשק API ציבורי יספק את ה-stubs הציבוריים לכולם.

דוגמאות ומקורות
המאפיינים 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 מומלץ (אבל לא נדרש) להפעיל במפורש את היקפי ה-API שבהם רוצים להשתמש במכונות java_sdk_library
חדשות. אפשר גם (אופציונלי) להעביר מכונות 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 שנמצאות ב-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 library build.
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
.
כשמשחררים את הגרסה, אפשר לקבל את רשימות הקבצים והספריות של ה-stubs של ה-API באמצעות build של 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
מכיל קובצי 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