Google is committed to advancing racial equity for Black communities. See how.
ترجمت واجهة Cloud Translation API‏ هذه الصفحة.
Switch to English

HIDL جافا

أعاد Android 8.0 تصميم نظام التشغيل Android لتحديد واجهات واضحة بين نظام Android المستقل عن الجهاز والرمز الخاص بالجهاز والمورد. قام Android بالفعل بتعريف العديد من هذه الواجهات في شكل واجهات HAL ، والتي تم تعريفها على أنها رؤوس C في hardware/libhardware . استبدلت HIDL واجهات HAL هذه بواجهات مستقرة ذات إصدار ، والتي يمكن أن تكون في Java (الموضحة أدناه) أو كواجهات HIDL من جانب العميل والخادم في C ++ .

تهدف واجهات HIDL إلى استخدامها بشكل أساسي من التعليمات البرمجية الأصلية ، ونتيجة لذلك تركز HIDL على الإنشاء التلقائي للكود الفعال في C ++. ومع ذلك ، يجب أيضًا أن تكون واجهات HIDL قادرة على استخدامها مباشرة من Java لأن بعض أنظمة Android الفرعية (مثل Telephony) ستحتوي على الأرجح على واجهات Java HIDL.

تصف الصفحات في هذا القسم الواجهة الأمامية لـ Java لواجهات HIDL ، وتفاصيل كيفية إنشاء الخدمات وتسجيلها واستخدامها ، وتشرح كيفية تفاعل عملاء HALs و HAL المكتوبون في Java مع نظام HIDL RPC.

كونك عميل

هذا مثال على عميل لواجهة IFoo في الحزمة android.hardware.foo@1.0 مسجلة كاسم default للخدمة وخدمة إضافية باسم خدمة مخصصة second_impl .

إضافة مكتبات

تحتاج إلى إضافة التبعيات على مكتبة HIDL stub المقابلة إذا كنت تريد استخدامها. عادة ، هذه مكتبة ثابتة:

// 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

اعتبارات إضافية لإضافة مكتبات في Android 10

إذا كان لديك تطبيق نظام / بائع يستهدف نظام Android 10 والإصدارات الأحدث ، فيجب عليك تضمين هذه المكتبات بشكل ثابت. بالنسبة للتطبيقات القديمة ، يتم الاحتفاظ بالسلوك القديم. بدلاً من ذلك ، من الممكن استخدام فئات HIDL فقط من JARs المخصصة المثبتة على الجهاز مع توفر Java APIs المستقرة باستخدام آلية uses-library الحالية لتطبيقات النظام. لتوفير مساحة على الجهاز ، هذه هي الطريقة الموصى بها. لمزيد من التفاصيل ، راجع تنفيذ مكتبة Java SDK .

بدءًا من 10 ، تتوفر أيضًا إصدارات "ضحلة" من هذه المكتبات. وتشمل هذه الفئة المعنية ولكنها لا تتضمن أيًا من الفئات التابعة. على سبيل المثال، android.hardware.foo-V1.0-java-shallow يشمل الفئات في حزمة فو، ولكن لا يشمل دروسا في 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 لتجنب تكرار التعليمات البرمجية واستخدام تطبيقات النظام / البائع لواجهات برمجة التطبيقات المخفية .

تعديل مصدر جافا الخاص بك

يوجد إصدار واحد فقط ( @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(…);

تقديم خدمة

قد تحتاج التعليمات البرمجية الإطارية في Java إلى خدمة الواجهات لتلقي عمليات الاسترجاعات غير المتزامنة من HALs.

بالنسبة لواجهة 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 ، الذي يغلف واجهة Java ورمز الوكيل /tmp/android/hardware/foo/1.0/IFooCallback.java (كلاهما الوكيل و stubs متوافق مع الواجهة).

-Lmakefile يولد القواعد التي تقوم بتشغيل هذا الأمر في وقت -Lmakefile وتسمح لك بتضمين android.hardware.foo-V1.0-java -Lmakefile بالملفات المناسبة. يمكن العثور على البرنامج النصي الذي يقوم بذلك تلقائيًا لمشروع مليء hardware/interfaces/update-makefiles.sh في hardware/interfaces/update-makefiles.sh . المسارات في هذا المثال نسبية ؛ يمكن أن تكون الأجهزة / الواجهات دليلًا مؤقتًا ضمن شجرة التعليمات البرمجية الخاصة بك لتمكينك من تطوير HAL قبل نشره.

تشغيل الخدمة

يوفر HAL واجهة IFoo ، والتي يجب أن تقوم بعمليات رد IFooCallback غير متزامنة إلى إطار العمل عبر واجهة 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 امتداد الواجهة 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.
}