Google is committed to advancing racial equity for Black communities. See how.
דף זה תורגם על ידי Cloud Translation API.
Switch to English

HIDL Java

אנדרואיד 8.0 ארכיב מחדש את מערכת ההפעלה אנדרואיד כדי להגדיר ממשקים ברורים בין פלטפורמת אנדרואיד שאינה תלויה במכשיר לבין קוד ספציפי למכשיר ולספק. אנדרואיד כבר הגדירה ממשקים רבים כאלה בצורה של ממשקי HAL, שהוגדרו ככותרות C hardware/libhardware . HIDL החליף ממשקי HAL אלה בממשקים יציבים ומותקנים, שיכולים להיות ב- Java (שתואר להלן) או כממשקי HIDL בצד הלקוח והשרת ב- C ++ .

ממשקי HIDL מיועדים לשימוש בעיקר מקוד מקורי, וכתוצאה מכך HIDL מתמקדת בייצור אוטומטי של קוד יעיל ב- C ++. עם זאת, ממשקי HIDL חייבים להיות מסוגלים לשמש ישירות גם מג'אווה שכן ככל הנראה בחלק מתתי מערכות האנדרואיד (כגון טלפוניה) יהיו ממשקי Java HIDL.

העמודים בחלק זה מתארים את חזית ה- Java עבור ממשקי HIDL, מפרטים כיצד ליצור, לרשום ולהשתמש בשירותים, ולהסביר כיצד HALs ולקוחות HAL הכתובים ב- Java מתקשרים עם מערכת HIDL RPC.

להיות לקוח

זוהי דוגמה ללקוח עבור ממשק IFoo בחבילה android.hardware.foo@1.0 שרשום default לשירות ושירות נוסף עם שם השירות המותאם אישית second_impl .

הוספת ספריות

עליך להוסיף תלות בספריית HIDL המתאימה אם ברצונך להשתמש בה. בדרך כלל זוהי ספרייה סטטית:

// in Android.bp
static_libs: [ "android.hardware.foo-V1.0-java", ],
// in Android.mk
LOCAL_STATIC_JAVA_LIBRARIES += android.hardware.foo-V1.0-java

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

// in Android.bp
libs: [ "android.hardware.foo-V1.0-java", ],
// in Android.mk
LOCAL_JAVA_LIBRARIES += android.hardware.foo-V1.0-java

שיקולים נוספים להוספת ספריות באנדרואיד 10

אם יש לך אפליקציית מערכת / ספק המכוונת ל- Android 10 ואילך, עליך לכלול באופן סטטי ספריות אלה. עבור אפליקציות ישנות יותר, ההתנהגות הישנה נשמרת. לחלופין, ניתן להשתמש רק בכיתות HIDL מ- JAR מותאמות אישית המותקנות בהתקן עם ממשקי API יציבים של Java הנגישים באמצעות מנגנון uses-library הקיים עבור אפליקציות מערכת. על מנת לחסוך מקום במכשיר, זו הגישה המומלצת. לפרטים נוספים, ראה יישום ספריית Java SDK .

החל מ -10, קיימות גם גרסאות "רדודות" של ספריות אלה. אלה כוללים את הכיתה המדוברת, אך אינם כוללים אף אחד מהשיעורים התלויים. לדוגמה, android.hardware.foo-V1.0-java-shallow כולל שיעורים בחבילה foo, אך אינו כולל שיעורים ב- android.hidl.base-V1.0-java , המכיל את מחלקת הבסיס של כל HIDL ממשקים. אם אתה יוצר ספריה שכבר יש לה שיעורי בסיס של הממשק המועדף כתלות, אתה יכול להשתמש בפעולות הבאות:

// in Android.bp
static_libs: [ "android.hardware.foo-V1.0-java-shallow", ],
// in Android.mk
LOCAL_STATIC_JAVA_LIBRARIES += android.hardware.foo-V1.0-java-shallow

ספריות בסיס HIDL ומנהלים אינן זמינות עוד בנתיב האתחול. במקום זאת, הם הועברו למרחב שמות חדש עם jarjar . מודולים בשביל הכיתה של האתחול המשתמשים ב- HIDL צריכים להשתמש בגרסאות הרדודות של ספריות אלה וכן להוסיף jarjar_rules: ":framework-jarjar-rules" ל- Android.bp שלהם על מנת למנוע קוד כפול ושימוש באפליקציות מערכת / ספקים להשתמש בממשקי API מוסתרים. .

שינוי מקור ה- Java שלך

יש רק גרסה אחת ( @1.0 ) של שירות זה, ולכן קוד זה מאחזר רק את הגרסה הזו. ראה הרחבות ממשק כיצד להתמודד עם מספר גרסאות שונות של השירות.

import android.hardware.foo.V1_0.IFoo;
...
// retry to wait until the service starts up if it is in the manifest
IFoo server = IFoo.getService(true /* retry */); // throws NoSuchElementException if not available
IFoo anotherServer = IFoo.getService("second_impl", true /* retry */);
server.doSomething(…);

מתן שירות

קוד מסגרת בג'אווה עשוי להזדקק לשרת ממשקים כדי לקבל שיחות חוזר אסינכרוניות מ- HAL.

עבור ממשק IFooCallback בגרסה 1.0 של חבילת android.hardware.foo , אתה יכול ליישם את הממשק שלך ב- Java באמצעות השלבים הבאים:

  1. הגדר את הממשק שלך ב- HIDL.
  2. פתח /tmp/android/hardware/foo/IFooCallback.java כהפניה.
  3. צור מודול חדש ליישום Java שלך.
  4. בדוק את המחלקה המופשטת android.hardware.foo.V1_0.IFooCallback.Stub , ואז כתוב מחלקה חדשה כדי להרחיב אותה וליישם את השיטות המופשטות.

הצגת קבצים שנוצרו אוטומטית

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

hidl-gen -o /tmp -Ljava \
  -randroid.hardware:hardware/interfaces \
  -randroid.hidl:system/libhidl/transport android.hardware.foo@1.0

פקודות אלה מייצרות את הספרייה /tmp/android/hardware/foo/1.0 . עבור hardware/interfaces/foo/1.0/IFooCallback.hal הקבצים hardware/interfaces/foo/1.0/IFooCallback.hal , זה מייצר את הקובץ /tmp/android/hardware/foo/1.0/IFooCallback.java , /tmp/android/hardware/foo/1.0/IFooCallback.java את ממשק Java, קוד ה- proxy וה- stubs (שניהם proxy ותלים תואמים את הממשק).

-Lmakefile מייצר את הכללים המריצים פקודה זו בזמן הבנייה ומאפשרים לך לכלול את android.hardware.foo-V1.0-java ולקשר כנגד הקבצים המתאימים. סקריפט שעושה זאת באופן אוטומטי לפרויקט מלא בממשקים ניתן למצוא hardware/interfaces/update-makefiles.sh . הנתיבים בדוגמה זו הם יחסית; חומרה / ממשקים יכולים להיות ספריה זמנית מתחת לעץ הקוד שלך כדי לאפשר לך לפתח HAL לפני פרסום זה.

הפעלת שירות

ה- HAL מספקת את IFoo ממשק, אשר חייב לעשות הגיעו ליעדן אסינכרוני למסגרת מעל IFooCallback ממשק. ממשק IFooCallback אינו רשום בשמו כשירות שניתן לגלות; במקום זאת, IFoo חייבת להכיל שיטה כגון setFooCallback(IFooCallback x) .

כדי להגדיר IFooCallback מגירסה 1.0 של android.hardware.foo החבילה, להוסיף android.hardware.foo-V1.0-java כדי Android.mk . הקוד להפעלת השירות הוא:

import android.hardware.foo.V1_0.IFoo;
import android.hardware.foo.V1_0.IFooCallback.Stub;
....
class FooCallback extends IFooCallback.Stub {
    // implement methods
}
....
// Get the service you will be receiving callbacks from.
// This also starts the threadpool for your callback service.
IFoo server = IFoo.getService(true /* retry */); // throws NoSuchElementException if not available
....
// This must be a persistent instance variable, not local,
//   to avoid premature garbage collection.
FooCallback mFooCallback = new FooCallback();
....
// Do this once to create the callback service and tell the "foo-bar" service
server.setFooCallback(mFooCallback);

הרחבות ממשק

בהנחה ששירות נתון מיישם את ממשק IFoo בכל המכשירים, ייתכן שבמכשיר מסוים השירות עשוי לספק יכולות נוספות המיושמות בסיומת הממשק IBetterFoo , כדלקמן:

interface IFoo {
   ...
};

interface IBetterFoo extends IFoo {
   ...
};

קוד שיחה המודע לממשק המורחב יכול להשתמש בשיטת Java של castFrom() כדי להטיל את ממשק הבסיס בבטחה לממשק המורחב:

IFoo baseService = IFoo.getService(true /* retry */); // throws NoSuchElementException if not available
IBetterFoo extendedService = IBetterFoo.castFrom(baseService);
if (extendedService != null) {
  // The service implements the extended interface.
} else {
  // The service implements only the base interface.
}