एचआईडीएल जावा, एचआईडीएल जावा, एचआईडीएल जावा

एंड्रॉइड 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

एंड्रॉइड 10 में लाइब्रेरी जोड़ने के लिए अतिरिक्त विचार

यदि आपके पास एक सिस्टम या विक्रेता ऐप है जो एंड्रॉइड 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 का उपयोग करने वाले बूट क्लासपाथ पर मॉड्यूल को इन जावा लाइब्रेरीज़ के उथले वेरिएंट का उपयोग करना होगा और बूट क्लासपाथ में मौजूद इन लाइब्रेरीज़ के संस्करण का उपयोग करने के लिए अपने Android.bp में jarjar_rules: ":framework-jarjar-rules" जोड़ना होगा।

अपने जावा स्रोत को संशोधित करना

इस सेवा का केवल एक संस्करण ( @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 इंटरफ़ेस के लिए, आप निम्न चरणों का उपयोग करके जावा में अपना इंटरफ़ेस लागू कर सकते हैं:

  1. HIDL में अपना इंटरफ़ेस परिभाषित करें।
  2. संदर्भ के रूप में /tmp/android/hardware/foo/IFooCallback.java खोलें।
  3. अपने जावा कार्यान्वयन के लिए एक नया मॉड्यूल बनाएं।
  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 के लिए, यह फ़ाइल /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.mk में android.hardware.foo-V1.0-java जोड़ें। सेवा चलाने का कोड है:

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.
}