एंड्रॉइड 8.0 में डिवाइस-स्वतंत्र एंड्रॉइड प्लेटफॉर्म और डिवाइस- और विक्रेता-विशिष्ट कोड के बीच स्पष्ट इंटरफेस को परिभाषित करने के लिए एंड्रॉइड ओएस को फिर से आर्किटेक्ट किया गया था। एंड्रॉइड ने पहले से ही ऐसे कई इंटरफेस को एचएएल इंटरफेस के रूप में परिभाषित किया है, जिन्हें hardware/libhardware
में सी हेडर के रूप में परिभाषित किया गया है। एचआईडीएल ने इन एचएएल इंटरफेस को स्थिर, संस्करण वाले इंटरफेस के साथ बदल दिया, जो या तो जावा में हो सकता है (नीचे वर्णित है) या क्लाइंट- और सर्वर-साइड एचआईडीएल इंटरफेस सी ++ में हो सकता है।
एचआईडीएल इंटरफेस मुख्य रूप से मूल कोड से उपयोग किए जाने का इरादा है, और परिणामस्वरूप एचआईडीएल सी ++ में कुशल कोड के स्वत: पीढ़ी पर केंद्रित है। हालांकि, एचआईडीएल इंटरफेस सीधे जावा से उपयोग के लिए भी उपलब्ध होना चाहिए, क्योंकि कुछ एंड्रॉइड सबसिस्टम (जैसे टेलीफोनी) में जावा एचआईडीएल इंटरफेस हैं।
इस खंड के पृष्ठ एचआईडीएल इंटरफेस के लिए जावा फ्रंटएंड का वर्णन करते हैं, सेवाओं को बनाने, पंजीकृत करने और उपयोग करने का विवरण देते हैं, और बताते हैं कि जावा में लिखे गए एचएएल और एचएएल क्लाइंट एचआईडीएल आरपीसी सिस्टम के साथ कैसे इंटरैक्ट करते हैं।
एक ग्राहक होने के नाते
यह पैकेज android.hardware.foo@1.0
में इंटरफ़ेस IFoo
के लिए क्लाइंट का एक उदाहरण है जो सेवा नाम 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 में लाइब्रेरी जोड़ने के लिए अतिरिक्त विचार
यदि आपके पास एक सिस्टम या विक्रेता ऐप है जो Android 10 या उच्चतर को लक्षित करता है, तो आप इन पुस्तकालयों को स्थिर रूप से शामिल कर सकते हैं। आप सिस्टम ऐप्स के लिए मौजूदा uses-library
तंत्र का उपयोग करके उपलब्ध स्थिर जावा एपीआई के साथ डिवाइस पर स्थापित कस्टम जेएआर से (केवल) एचआईडीएल कक्षाओं का भी उपयोग कर सकते हैं। बाद वाला तरीका डिवाइस पर जगह बचाता है। अधिक जानकारी के लिए, जावा एसडीके लाइब्रेरी लागू करना देखें। पुराने ऐप्स के लिए, पुराना व्यवहार सुरक्षित रहता है।
एंड्रॉइड 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
एचआईडीएल आधार और प्रबंधक पुस्तकालय भी अब ऐप्स के लिए बूट क्लासपाथ पर उपलब्ध नहीं हैं (पहले, उन्हें कभी-कभी एंड्रॉइड के प्रतिनिधि-प्रथम क्लासलोडर के कारण छिपे हुए एपीआई के रूप में उपयोग किया जाता था)। इसके बजाय, उन्हें 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(…);
सेवा प्रदान करना
जावा में फ्रेमवर्क कोड को एचएएल से एसिंक्रोनस कॉलबैक प्राप्त करने के लिए इंटरफेस की आवश्यकता हो सकती है।
android.hardware.foo
पैकेज के संस्करण 1.0 में IFooCallback
इंटरफ़ेस के लिए, आप निम्न चरणों का उपयोग करके जावा में अपना इंटरफ़ेस लागू कर सकते हैं:
- HIDL में अपने इंटरफ़ेस को परिभाषित करें।
- संदर्भ के रूप में
/tmp/android/hardware/foo/IFooCallback.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/हार्डवेयर/foo/1.0/ /tmp/android/hardware/foo/1.0/IFooCallback.java
उत्पन्न करता है, जो जावा इंटरफ़ेस, प्रॉक्सी कोड और स्टब्स (दोनों प्रॉक्सी) को इनकैप्सुलेट करता है और स्टब्स इंटरफेस के अनुरूप हैं)।
-Lmakefile
ऐसे नियम बनाता है जो इस कमांड को बिल्ड टाइम पर चलाते हैं और आपको android.hardware.foo-V1.0-java
को शामिल करने और उपयुक्त फाइलों के खिलाफ लिंक करने की अनुमति देते हैं। एक स्क्रिप्ट जो इंटरफेस से भरे प्रोजेक्ट के लिए स्वचालित रूप से ऐसा करती है, उसे hardware/interfaces/update-makefiles.sh
पर पाया जा सकता है। इस उदाहरण में पथ सापेक्ष हैं; हार्डवेयर/इंटरफ़ेस आपके कोड ट्री के तहत एक अस्थायी निर्देशिका हो सकती है ताकि आप इसे प्रकाशित करने से पहले एक एचएएल विकसित कर सकें।
सेवा चलाना
HAL IFoo
इंटरफ़ेस प्रदान करता है, जिसे IFooCallback
इंटरफ़ेस पर फ्रेमवर्क में एसिंक्रोनस कॉलबैक करना चाहिए। IFooCallback
इंटरफ़ेस खोज योग्य सेवा के रूप में नाम से पंजीकृत नहीं है; इसके बजाय, IFoo
में एक विधि होनी चाहिए जैसे कि setFooCallback(IFooCallback x)
।
android.hardware.foo
पैकेज के संस्करण 1.0 से IFooCallback
सेट करने के लिए, 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()
जावा विधि का उपयोग बेस इंटरफ़ेस को विस्तारित इंटरफ़ेस में सुरक्षित रूप से डालने के लिए कर सकता है:
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. }