في Android 8.0، أُعيد تصميم نظام التشغيل Android لتحديد واجهات واضحة.
بين نظام Android الأساسي المستقل والجهاز وال
الرمز. سبق أن حدَّد نظام التشغيل Android العديد من هذه الواجهات على شكل HAL.
الواجهات، بوصفها عناوين C في hardware/libhardware
. مؤسسة HIDL
استبدال واجهات HAL هذه بواجهات مستقرة ذات إصدارات مختلفة،
إما أن تكون بلغة Java (الموضّحة أدناه) أو تكون ببروتوكول HIDL من جهة العميل والخادم.
الواجهات في C++.
تم تصميم واجهات HIDL للاستخدام بشكل أساسي من خلال الرموز البرمجية الأصلية، يركّز HIDL على الإنشاء التلقائي للرموز الفعّالة في لغة C++. ومع ذلك، يجب أن تتوفر أيضًا واجهات HIDL للاستخدام مباشرةً من Java، مثل بعض أنظمة للأنظمة الفرعية (مثل الاتصال الهاتفي) واجهات 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
اعتبارات أخرى لإضافة المكتبات في Android 10
إذا كان لديك تطبيق نظام أو مورّد يستهدف الإصدار 10 من نظام التشغيل Android أو الإصدارات الأحدث،
يمكنك تضمين هذه المكتبات بشكل ثابت. يمكنك أيضًا استخدام صفوف HIDL (فقط).
من ملفات JAR المخصصة والمثبتة على الجهاز مع إتاحة واجهات برمجة تطبيقات Java الثابتة
باستخدام آلية uses-library
الحالية لتطبيقات النظام. تشير رسالة الأشكال البيانية
فإن الطريقة الأخيرة توفر مساحة على الجهاز. لمزيد من التفاصيل، يُرجى الاطّلاع على تنفيذ مكتبة حزمة تطوير البرامج (SDK) بلغة Java. بالنسبة
التطبيقات القديمة، يتم الاحتفاظ بالسلوك القديم.
بدءًا من Android 10، "shallow" نُسخًا من هذه المكتبات
تتوفر أيضًا. وتشمل هذه الفئة الفئة المعنية ولكنها لا تتضمن أي
الفئات التابعة. على سبيل المثال:
يتضمن 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 الأساسية والمديرة متوفّرة أيضًا عند التشغيل.
classpath للتطبيقات (كانت تُستخدَم سابقًا كواجهة برمجة تطبيقات مخفية، بسبب
برنامج تحميل الفئة الأولى المفوَّض في Android). وبدلاً من ذلك، تم نقلهم إلى
مساحة الاسم مع jarjar
، والتطبيقات التي تستخدم هذه (بالضرورة خاصة)
التطبيقات) على نُسخ منفصلة خاصة بها. الوحدات في مسار التمهيد باستخدام
يجب أن يستخدم HIDL المتغيرات السطحية لمكتبات Java هذه، وأن تضيف
في jarjar_rules: ":framework-jarjar-rules"
Android.bp
لاستخدام نسخة هذه المكتبات المتوفّرة
في مسار فئة التمهيد.
تعديل مصدر 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(…);
تقديم خدمة
قد يحتاج رمز إطار العمل في Java إلى عرض واجهات لتلقّي الرسائل غير المتزامنة عمليات معاودة الاتصال من HALs.
بالنسبة إلى واجهة IFooCallback
في الإصدار 1.0 من
حزمة android.hardware.foo
، يمكنك تنفيذ واجهتك في
Java باتّباع الخطوات التالية:
- عرِّف واجهتك في HIDL.
- فتح "
/tmp/android/hardware/foo/IFooCallback.java
" كـ المرجع. - أنشئ وحدة جديدة لتنفيذ Java.
- تفحّص الفئة التجريدية
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
، يؤدي هذا إلى إنشاء
الملف /tmp/android/hardware/foo/1.0/IFooCallback.java
، الذي
تغليف واجهة Java، وكود الوكيل، والأجزاء البديلة (كل من الخادم الوكيل
الرموز البديلة مع الواجهة).
ينشئ -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 from which you will be receiving callbacks. // 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 { ... };
يمكن لرمز الاتصال الذي لديه معرفة بالواجهة الموسّعة أن يستخدم
castFrom()
طريقة Java لإرسال الواجهة الأساسية إلى
الواجهة الموسعة:
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. }