स्थिर एआईडीएल

संग्रह की मदद से व्यवस्थित रहें अपनी प्राथमिकताओं के आधार पर, कॉन्टेंट को सेव करें और कैटगरी में बांटें.

एंड्रॉइड 10 स्थिर एंड्रॉइड इंटरफेस डेफिनिशन लैंग्वेज (एआईडीएल) के लिए समर्थन जोड़ता है, एआईडीएल इंटरफेस द्वारा प्रदान किए गए एप्लिकेशन प्रोग्राम इंटरफेस (एपीआई) / एप्लिकेशन बाइनरी इंटरफेस (एबीआई) का ट्रैक रखने का एक नया तरीका। स्थिर एआईडीएल में एआईडीएल से निम्नलिखित प्रमुख अंतर हैं:

  • इंटरफेस को बिल्ड सिस्टम में aidl_interfaces के साथ परिभाषित किया गया है।
  • इंटरफेस में केवल संरचित डेटा हो सकता है। वांछित प्रकारों का प्रतिनिधित्व करने वाले पार्सलेबल स्वचालित रूप से उनकी एआईडीएल परिभाषा के आधार पर बनाए जाते हैं और स्वचालित रूप से मार्शल और अनमरशाल्ड होते हैं।
  • इंटरफेस को स्थिर (पीछे-संगत) के रूप में घोषित किया जा सकता है। जब ऐसा होता है, तो उनके एपीआई को एआईडीएल इंटरफ़ेस के बगल में एक फ़ाइल में ट्रैक और संस्करणित किया जाता है।

एआईडीएल इंटरफ़ेस को परिभाषित करना

aidl_interface की परिभाषा इस तरह दिखती है:

aidl_interface {
    name: "my-aidl",
    srcs: ["srcs/aidl/**/*.aidl"],
    local_include_dir: "srcs/aidl",
    imports: ["other-aidl"],
    versions_with_info: [
        {
            version: "1",
            imports: ["ohter-aidl-V1"],
        },
        {
            version: "2",
            imports: ["other-aidl-V3"],
        }
    ],
    stability: "vintf",
    backend: {
        java: {
            enabled: true,
            platform_apis: true,
        },
        cpp: {
            enabled: true,
        },
        ndk: {
            enabled: true,
        },
        rust: {
            enabled: true,
        },
    },

}
  • name : एआईडीएल इंटरफेस मॉड्यूल का नाम जो विशिष्ट रूप से एआईडीएल इंटरफेस की पहचान करता है।
  • srcs : इंटरफ़ेस बनाने वाली AIDL स्रोत फ़ाइलों की सूची। पैकेज com.acme में परिभाषित एआईडीएल प्रकार Foo के लिए पथ <base_path>/com/acme/Foo.aidl पर होना चाहिए, जहां <base_path> उस निर्देशिका से संबंधित कोई निर्देशिका हो सकती है जहां Android.bp है। उपरोक्त उदाहरण में, <base_path> srcs/aidl है।
  • local_include_dir : वह पथ जहाँ से पैकेज का नाम शुरू होता है। यह ऊपर बताए गए <base_path> से मेल खाता है।
  • imports : यह उपयोग करने वाले aidl_interface मॉड्यूल की एक सूची। यदि आपका कोई एआईडीएल इंटरफेस इंटरफेस का उपयोग करता है या किसी अन्य aidl_interface से पार्सल करने योग्य है, तो उसका नाम यहां रखें। नवीनतम संस्करण को संदर्भित करने के लिए यह अपने आप में नाम हो सकता है, या किसी विशिष्ट संस्करण को संदर्भित करने के लिए संस्करण प्रत्यय (जैसे -V1 ) के साथ नाम हो सकता है। संस्करण निर्दिष्ट करना Android 12 के बाद से समर्थित है
  • versions : इंटरफ़ेस के पिछले संस्करण जो api_dir के तहत जमे हुए हैं, Android 11 में शुरू होकर, versions को aidl_api/ name के तहत जमे हुए हैं। यदि इंटरफ़ेस का कोई स्थिर संस्करण नहीं है, तो इसे निर्दिष्ट नहीं किया जाना चाहिए, और संगतता जाँच नहीं होगी। इस फ़ील्ड को 13 और उच्चतर के लिए versions_with_info से बदल दिया गया है।
  • version_with_info : versions_with_info की सूची, जिनमें से प्रत्येक में एक जमे हुए संस्करण का नाम है और अन्य सहायता_इंटरफेस मॉड्यूल के संस्करण आयात के साथ एक सूची है जो कि सहायता_इंटरफेस के इस संस्करण को आयात किया गया है। एआईडीएल इंटरफेस आईएफएसीई के संस्करण वी की परिभाषा aidl_api/ IFACE / V पर स्थित है। इस फ़ील्ड को Android 13 में पेश किया गया था, और इसे सीधे Android.bp में संशोधित नहीं किया जाना चाहिए। *-update- *-update-api या *-freeze-api को कॉल करके फ़ील्ड को जोड़ा या अपडेट किया जाता है। साथ ही, जब कोई उपयोगकर्ता *-update- *-update-api या *-freeze-api आह्वान करता है तो versions फ़ील्ड स्वचालित रूप से version_with_info में माइग्रेट हो जाते versions_with_info
  • stability : इस इंटरफ़ेस की स्थिरता के वादे के लिए वैकल्पिक ध्वज। वर्तमान में केवल "vintf" का समर्थन करता है। यदि यह सेट नहीं है, तो यह इस संकलन संदर्भ में स्थिरता के साथ एक इंटरफ़ेस से मेल खाता है (इसलिए यहां लोड किया गया इंटरफ़ेस केवल एक साथ संकलित चीजों के साथ उपयोग किया जा सकता है, उदाहरण के लिए system.img पर)। यदि इसे "vintf" पर सेट किया जाता है, तो यह एक स्थिरता के वादे के अनुरूप होता है: इंटरफ़ेस को तब तक स्थिर रखा जाना चाहिए जब तक इसका उपयोग किया जाता है।
  • gen_trace : अनुरेखण को चालू या बंद करने के लिए वैकल्पिक ध्वज। डिफ़ॉल्ट false है।
  • host_supported : वैकल्पिक ध्वज जो true पर सेट होने पर उत्पन्न पुस्तकालयों को मेजबान वातावरण में उपलब्ध कराता है।
  • unstable : वैकल्पिक ध्वज का उपयोग यह चिह्नित करने के लिए किया जाता है कि इस इंटरफ़ेस को स्थिर होने की आवश्यकता नहीं है। जब इसे सही पर सेट किया जाता true , तो बिल्ड सिस्टम इंटरफ़ेस के लिए न तो एपीआई डंप बनाता है और न ही इसे अपडेट करने की आवश्यकता होती है।
  • backend.<type>.enabled : ये झंडे प्रत्येक बैकएंड को टॉगल करते हैं जिसके लिए AIDL कंपाइलर कोड उत्पन्न करता है। वर्तमान में, चार बैकएंड समर्थित हैं: Java, C++, NDK, और Rust। जावा, सी ++, और एनडीके बैकएंड डिफ़ॉल्ट रूप से सक्षम हैं। यदि इन तीनों में से किसी बैकएंड की आवश्यकता नहीं है, तो इसे स्पष्ट रूप से अक्षम करने की आवश्यकता है। जंग डिफ़ॉल्ट रूप से अक्षम है।
  • backend.<type>.apex_available
  • backend.[cpp|java].gen_log : वैकल्पिक फ़्लैग जो नियंत्रित करता है कि लेन-देन के बारे में जानकारी एकत्र करने के लिए अतिरिक्त कोड उत्पन्न करना है या नहीं।
  • backend.[cpp|java].vndk.enabled : इस इंटरफ़ेस को VNDK का हिस्सा बनाने के लिए वैकल्पिक फ़्लैग। डिफ़ॉल्ट false है।
  • backend.java.platform_apis : वैकल्पिक फ़्लैग जो यह नियंत्रित करता है कि क्या जावा स्टब लाइब्रेरी को प्लेटफ़ॉर्म से निजी API के विरुद्ध बनाया गया है। stability "vintf" पर सेट होने पर इसे "true" पर सेट किया जाना चाहिए।
  • backend.java.sdk_version : एसडीके के उस संस्करण को निर्दिष्ट करने के लिए वैकल्पिक ध्वज जिसके विरुद्ध जावा स्टब लाइब्रेरी बनाई गई है। डिफ़ॉल्ट "system_current" है। इसे तब सेट नहीं किया जाना चाहिए जब backend.java.platform_apis सच हो।
  • backend.java.platform_apis : वैकल्पिक ध्वज जिसे true पर सेट किया जाना चाहिए जब जनरेट की गई लाइब्रेरी को SDK के बजाय प्लेटफ़ॉर्म API के विरुद्ध बनाने की आवश्यकता हो।

संस्करणों और सक्षम बैकएंड के प्रत्येक संयोजन के लिए, एक स्टब लाइब्रेरी बनाई जाती है। किसी विशिष्ट बैकएंड के लिए स्टब लाइब्रेरी के विशिष्ट संस्करण को कैसे संदर्भित किया जाए, इसके लिए मॉड्यूल नामकरण नियम देखें।

एआईडीएल फाइलें लिखना

स्थिर एआईडीएल में इंटरफेस पारंपरिक इंटरफेस के समान हैं, इस अपवाद के साथ कि उन्हें असंरचित पार्सलेबल का उपयोग करने की अनुमति नहीं है (क्योंकि ये स्थिर नहीं हैं!)। स्थिर एआईडीएल में प्राथमिक अंतर यह है कि पार्सलयोग्य को कैसे परिभाषित किया जाता है। पहले, पार्सलयोग्य को अग्रेषित घोषित किया गया था; स्थिर एआईडीएल में, पार्सलेबल फ़ील्ड और चर स्पष्ट रूप से परिभाषित किए गए हैं।

// in a file like 'some/package/Thing.aidl'
package some.package;

parcelable SubThing {
    String a = "foo";
    int b;
}

boolean , char , float , double , byte , int , long और String के लिए वर्तमान में एक डिफ़ॉल्ट समर्थित (लेकिन आवश्यक नहीं) है। एंड्रॉइड 12 में, उपयोगकर्ता-परिभाषित गणनाओं के लिए डिफ़ॉल्ट भी समर्थित हैं। जब कोई डिफ़ॉल्ट निर्दिष्ट नहीं किया जाता है, तो 0-लाइक या खाली मान का उपयोग किया जाता है। शून्य एन्युमरेटर न होने पर भी डिफॉल्ट वैल्यू के बिना एन्यूमरेशन को 0 से इनिशियलाइज़ किया जाता है।

स्टब लाइब्रेरी का उपयोग करना

अपने मॉड्यूल पर निर्भरता के रूप में स्टब लाइब्रेरी जोड़ने के बाद, आप उन्हें अपनी फाइलों में शामिल कर सकते हैं। यहां बिल्ड सिस्टम में स्टब लाइब्रेरी के उदाहरण दिए गए हैं ( Android.mk का उपयोग लीगेसी मॉड्यूल परिभाषाओं के लिए भी किया जा सकता है):

cc_... {
    name: ...,
    shared_libs: ["my-module-name-cpp"],
    ...
}
# or
java_... {
    name: ...,
    // can also be shared_libs if desire is to load a library and share
    // it among multiple users or if you only need access to constants
    static_libs: ["my-module-name-java"],
    ...
}
# or
rust_... {
    name: ...,
    rust_libs: ["my-module-name-rust"],
    ...
}

सी ++ में उदाहरण:

#include "some/package/IFoo.h"
#include "some/package/Thing.h"
...
    // use just like traditional AIDL

जावा में उदाहरण:

import some.package.IFoo;
import some.package.Thing;
...
    // use just like traditional AIDL

जंग में उदाहरण:

use aidl_interface_name::aidl::some::package::{IFoo, Thing};
...
    // use just like traditional AIDL

वर्जनिंग इंटरफेस

नाम फू के साथ एक मॉड्यूल घोषित करना भी बिल्ड सिस्टम में एक लक्ष्य बनाता है जिसका उपयोग आप मॉड्यूल के एपीआई को प्रबंधित करने के लिए कर सकते हैं। निर्मित होने पर, foo-freeze-api Android संस्करण के आधार पर api_dir या aidl_api/ name के तहत एक नई API परिभाषा जोड़ता है, और एक .hash फ़ाइल जोड़ता है, दोनों इंटरफ़ेस के नए जमे हुए संस्करण का प्रतिनिधित्व करते हैं। foo-freeze-api संस्करण के लिए अतिरिक्त versions_with_info और imports को प्रतिबिंबित करने के लिए version_with_info गुण को भी अपडेट करता है। मूल रूप से, versions_with_info में imports को imports क्षेत्र से कॉपी किया जाता है। लेकिन नवीनतम स्थिर versions_with_info को आयात के लिए version_with_info में imports में निर्दिष्ट किया गया है जिसमें एक स्पष्ट संस्करण नहीं है। एक बार version_with_info संपत्ति निर्दिष्ट हो जाने के बाद, बिल्ड सिस्टम जमे हुए versions_with_info के बीच और टॉप ऑफ ट्री (टीओटी) और नवीनतम जमे हुए संस्करण के बीच संगतता जांच चलाता है।

इसके अलावा, आपको टीओटी संस्करण की एपीआई परिभाषा को प्रबंधित करने की आवश्यकता है। जब भी कोई एपीआई अपडेट किया जाता है, aidl_api/ name /current को अपडेट करने के लिए फू-अपडेट-एपीआई चलाएं जिसमें टीओटी संस्करण की एपीआई परिभाषा शामिल है।

इंटरफ़ेस की स्थिरता बनाए रखने के लिए, मालिक नए जोड़ सकते हैं:

  • एक इंटरफ़ेस के अंत के तरीके (या स्पष्ट रूप से परिभाषित नए धारावाहिकों के तरीके)
  • एक पार्सल योग्य के अंत में तत्व (प्रत्येक तत्व के लिए एक डिफ़ॉल्ट जोड़ने की आवश्यकता है)
  • लगातार मूल्य
  • एंड्रॉइड 11 में, एन्युमरेटर्स
  • Android 12 में, एक संघ के अंत तक फ़ील्ड

किसी अन्य कार्रवाई की अनुमति नहीं है, और कोई भी इंटरफ़ेस को संशोधित नहीं कर सकता है (अन्यथा वे स्वामी द्वारा किए गए परिवर्तनों के साथ टकराव का जोखिम उठाते हैं)।

यह जांचने के लिए कि रिलीज के लिए सभी इंटरफेस जमे हुए हैं, आप निम्नलिखित पर्यावरण चर सेट के साथ बना सकते हैं:

  • AIDL_FROZEN_REL=true m ... - निर्माण के लिए सभी स्थिर AIDL इंटरफेस को स्थिर करने की आवश्यकता होती है, जिसमें कोई owner: फ़ील्ड निर्दिष्ट नहीं है।
  • AIDL_FROZEN_OWNERS="aosp test" - बिल्ड के लिए सभी स्थिर AIDL इंटरफेस को owner: फ़ील्ड को "aosp" या "test" के रूप में निर्दिष्ट किया गया है।

आयात की स्थिरता

एक इंटरफ़ेस के जमे हुए संस्करणों के लिए आयात के संस्करणों को अद्यतन करना स्थिर एआईडीएल परत पर पीछे की ओर संगत है। हालाँकि, इन्हें अपडेट करने के लिए उन सभी सर्वरों और क्लाइंट्स को अपडेट करने की आवश्यकता होती है जो इंटरफ़ेस के पुराने संस्करण का उपयोग करते हैं, और विभिन्न प्रकार के संस्करणों को मिलाते समय कुछ एप्लिकेशन भ्रमित हो सकते हैं। आम तौर पर, टाइप-ओनली या कॉमन पैकेज के लिए, यह सुरक्षित है क्योंकि आईपीसी लेनदेन से अज्ञात प्रकार को संभालने के लिए कोड को पहले से ही लिखा जाना चाहिए।

एंड्रॉइड प्लेटफॉर्म कोड में android.hardware.graphics.common इस प्रकार के वर्जन अपग्रेड का सबसे बड़ा उदाहरण है।

संस्करणित इंटरफेस का उपयोग करना

इंटरफ़ेस के तरीके

रनटाइम पर, पुराने सर्वर पर नए तरीकों को कॉल करने का प्रयास करते समय, बैकएंड के आधार पर नए क्लाइंट को या तो त्रुटि या अपवाद मिलता है।

  • cpp बैकएंड को ::android::UNKNOWN_TRANSACTION मिलता है।
  • ndk बैकएंड को STATUS_UNKNOWN_TRANSACTION मिलता है।
  • java बैकएंड android.os.RemoteException एक संदेश के साथ मिलता है जिसमें कहा गया है कि एपीआई लागू नहीं किया गया है।

इसे संभालने के लिए रणनीतियों के लिए क्वेरी संस्करण और डिफ़ॉल्ट का उपयोग देखें।

पार्सलेबल

जब पार्सलयोग्य में नए फ़ील्ड जोड़े जाते हैं, तो पुराने क्लाइंट और सर्वर उन्हें छोड़ देते हैं। जब नए ग्राहक और सर्वर पुराने पार्सल प्राप्त करते हैं, तो नए फ़ील्ड के लिए डिफ़ॉल्ट मान स्वचालित रूप से भर जाते हैं। इसका मतलब है कि पार्सल योग्य सभी नए फ़ील्ड के लिए डिफ़ॉल्ट निर्दिष्ट करने की आवश्यकता है।

ग्राहकों को सर्वर से नए फ़ील्ड का उपयोग करने की उम्मीद नहीं करनी चाहिए जब तक कि वे नहीं जानते कि सर्वर उस संस्करण को कार्यान्वित कर रहा है जिसमें फ़ील्ड परिभाषित है ( क्वेरी संस्करण देखें)।

Enums और स्थिरांक

इसी तरह, ग्राहकों और सर्वरों को गैर-मान्यता प्राप्त निरंतर मूल्यों और प्रगणकों को उपयुक्त के रूप में या तो अस्वीकार या अनदेखा करना चाहिए, क्योंकि भविष्य में और जोड़े जा सकते हैं। उदाहरण के लिए, एक सर्वर को निरस्त नहीं करना चाहिए जब उसे एक एन्यूमरेटर प्राप्त होता है जिसके बारे में उसे पता नहीं होता है। इसे या तो इसे अनदेखा करना चाहिए, या कुछ वापस करना चाहिए ताकि ग्राहक को पता चले कि यह इस कार्यान्वयन में असमर्थित है।

यूनियन

यदि रिसीवर पुराना है और क्षेत्र के बारे में नहीं जानता है तो एक नए क्षेत्र के साथ संघ भेजने का प्रयास विफल हो जाता है। कार्यान्वयन संघ को नए क्षेत्र के साथ कभी नहीं देखेगा। यदि यह एकतरफ़ा लेन-देन है तो विफलता को नज़रअंदाज़ कर दिया जाता है; अन्यथा त्रुटि BAD_VALUE (C++ या NDK बैकएंड के लिए) या IllegalArgumentException (Java बैकएंड के लिए) है। त्रुटि प्राप्त होती है यदि क्लाइंट नए क्षेत्र में पुराने सर्वर पर यूनियन सेट भेज रहा है, या जब यह पुराने क्लाइंट को नए सर्वर से यूनियन प्राप्त कर रहा है।

मॉड्यूल नामकरण नियम

एंड्रॉइड 11 में, संस्करणों के प्रत्येक संयोजन और सक्षम बैकएंड के लिए, एक स्टब लाइब्रेरी मॉड्यूल स्वचालित रूप से बनाया जाता है। जोड़ने के लिए एक विशिष्ट स्टब लाइब्रेरी मॉड्यूल को संदर्भित करने के लिए, aidl_interface मॉड्यूल के नाम का उपयोग न करें, लेकिन स्टब लाइब्रेरी मॉड्यूल का नाम, जो कि ifacename - version - backend है, जहां

  • ifacename : aidl_interface मॉड्यूल का नाम
  • version या तो है
    • जमे हुए संस्करणों के लिए V version-number
    • V latest-frozen-version-number + 1 टिप-ऑफ-ट्री (अभी तक फ्रोजन) संस्करण के लिए
  • backend या तो है
    • java जावा बैकएंड के लिए,
    • cpp सी ++ बैकएंड के लिए,
    • ndk बैकएंड के लिए ndk या ndk_platform । पूर्व ऐप्स के लिए है, और बाद वाला प्लेटफ़ॉर्म उपयोग के लिए है,
    • rust बैकएंड के लिए जंग।

मान लें कि foo नाम वाला एक मॉड्यूल है और इसका नवीनतम संस्करण 2 है, और यह NDK और C++ दोनों का समर्थन करता है। इस मामले में, एआईडीएल इन मॉड्यूलों को उत्पन्न करता है:

  • संस्करण 1 के आधार पर
    • foo-V1-(java|cpp|ndk|ndk_platform|rust)
  • संस्करण 2 (नवीनतम स्थिर संस्करण) के आधार पर
    • foo-V2-(java|cpp|ndk|ndk_platform|rust)
  • टीओटी संस्करण के आधार पर
    • foo-V3-(java|cpp|ndk|ndk_platform|rust)

Android 11 की तुलना में,

  • foo- backend foo- V2 - backend बन जाता है
  • foo-unstable- backend , जो टीओटी संस्करण को संदर्भित करता है, फू- foo- V3 - backend बन जाता है

आउटपुट फ़ाइल नाम हमेशा मॉड्यूल नाम के समान होते हैं।

  • संस्करण 1 पर आधारित: foo-V1-(cpp|ndk|ndk_platform|rust).so
  • संस्करण 2 पर आधारित: foo-V2-(cpp|ndk|ndk_platform|rust).so
  • टीओटी संस्करण के आधार पर: foo-V3-(cpp|ndk|ndk_platform|rust).so

ध्यान दें कि एआईडीएल कंपाइलर या तो unstable संस्करण मॉड्यूल या स्थिर एआईडीएल इंटरफ़ेस के लिए गैर-संस्करण मॉड्यूल नहीं बनाता है। एंड्रॉइड 12 के अनुसार, एक स्थिर एआईडीएल इंटरफ़ेस से उत्पन्न मॉड्यूल नाम में हमेशा इसका संस्करण शामिल होता है।

नए मेटा इंटरफ़ेस तरीके

Android 10 स्थिर AIDL के लिए कई मेटा इंटरफ़ेस तरीके जोड़ता है।

दूरस्थ वस्तु के इंटरफ़ेस संस्करण को क्वेरी करना

क्लाइंट उस इंटरफ़ेस के संस्करण और हैश को क्वेरी कर सकता है जिसे दूरस्थ ऑब्जेक्ट कार्यान्वित कर रहा है और लौटाए गए मानों की तुलना उस इंटरफ़ेस के मानों से कर सकता है जिसका उपयोग क्लाइंट कर रहा है।

cpp बैकएंड के साथ उदाहरण:

sp<IFoo> foo = ... // the remote object
int32_t my_ver = IFoo::VERSION;
int32_t remote_ver = foo->getInterfaceVersion();
if (remote_ver < my_ver) {
  // the remote side is using an older interface
}

std::string my_hash = IFoo::HASH;
std::string remote_hash = foo->getInterfaceHash();

ndk (और ndk_platform ) बैकएंड के साथ उदाहरण:

IFoo* foo = ... // the remote object
int32_t my_ver = IFoo::version;
int32_t remote_ver = 0;
if (foo->getInterfaceVersion(&remote_ver).isOk() && remote_ver < my_ver) {
  // the remote side is using an older interface
}

std::string my_hash = IFoo::hash;
std::string remote_hash;
foo->getInterfaceHash(&remote_hash);

java बैकएंड के साथ उदाहरण:

IFoo foo = ... // the remote object
int myVer = IFoo.VERSION;
int remoteVer = foo.getInterfaceVersion();
if (remoteVer < myVer) {
  // the remote side is using an older interface
}

String myHash = IFoo.HASH;
String remoteHash = foo.getInterfaceHash();

जावा भाषा के लिए, दूरस्थ पक्ष को getInterfaceVersion() और getInterfaceHash() को निम्नानुसार लागू करना चाहिए (कॉपी/पेस्ट गलतियों से बचने के लिए IFoo के बजाय super का उपयोग किया जाता है। एनोटेशन @SuppressWarnings("static") को चेतावनियों को अक्षम करने की आवश्यकता हो सकती है, इस पर निर्भर करता है javac कॉन्फ़िगरेशन):

class MyFoo extends IFoo.Stub {
    @Override
    public final int getInterfaceVersion() { return super.VERSION; }

    @Override
    public final String getInterfaceHash() { return super.HASH; }
}

ऐसा इसलिए है क्योंकि उत्पन्न कक्षाएं ( IFoo , IFoo.Stub , आदि) क्लाइंट और सर्वर के बीच साझा की जाती हैं (उदाहरण के लिए, कक्षाएं बूट क्लासपाथ में हो सकती हैं)। जब कक्षाएं साझा की जाती हैं, तो सर्वर कक्षाओं के नवीनतम संस्करण से भी जुड़ा होता है, भले ही इसे इंटरफ़ेस के पुराने संस्करण के साथ बनाया गया हो। यदि यह मेटा इंटरफ़ेस साझा वर्ग में कार्यान्वित किया जाता है, तो यह हमेशा नवीनतम संस्करण लौटाता है। हालाँकि, उपरोक्त विधि को लागू करने से, इंटरफ़ेस का संस्करण संख्या सर्वर के कोड में एम्बेडेड होता है (क्योंकि IFoo.VERSION एक static final int है जो संदर्भित होने पर इनलाइन होता है) और इस प्रकार विधि सर्वर द्वारा बनाए गए सटीक संस्करण को वापस कर सकती है साथ।

पुराने इंटरफेस से निपटना

यह संभव है कि क्लाइंट को एआईडीएल इंटरफ़ेस के नए संस्करण के साथ अपडेट किया गया हो लेकिन सर्वर पुराने एआईडीएल इंटरफ़ेस का उपयोग कर रहा हो। ऐसे मामलों में, पुराने इंटरफ़ेस पर एक विधि को कॉल करने से UNKNOWN_TRANSACTION वापस आ जाता है।

स्थिर एआईडीएल के साथ, ग्राहकों का अधिक नियंत्रण होता है। ग्राहक पक्ष में, आप एआईडीएल इंटरफेस के लिए एक डिफ़ॉल्ट कार्यान्वयन सेट कर सकते हैं। डिफ़ॉल्ट कार्यान्वयन में एक विधि तभी लागू की जाती है जब दूरस्थ पक्ष में विधि लागू नहीं की जाती है (क्योंकि यह इंटरफ़ेस के पुराने संस्करण के साथ बनाया गया था)। चूंकि डिफ़ॉल्ट वैश्विक रूप से सेट किए गए हैं, इसलिए उन्हें संभावित रूप से साझा किए गए संदर्भों से उपयोग नहीं किया जाना चाहिए।

Android 13 और बाद में C++ में उदाहरण:

class MyDefault : public IFooDefault {
  Status anAddedMethod(...) {
   // do something default
  }
};

// once per an interface in a process
IFoo::setDefaultImpl(::android::sp<MyDefault>::make());

foo->anAddedMethod(...); // MyDefault::anAddedMethod() will be called if the
                         // remote side is not implementing it

जावा में उदाहरण:

IFoo.Stub.setDefaultImpl(new IFoo.Default() {
    @Override
    public xxx anAddedMethod(...)  throws RemoteException {
        // do something default
    }
}); // once per an interface in a process


foo.anAddedMethod(...);

आपको एआईडीएल इंटरफेस में सभी विधियों का डिफ़ॉल्ट कार्यान्वयन प्रदान करने की आवश्यकता नहीं है। रिमोट साइड में लागू होने की गारंटी देने वाली विधियाँ (क्योंकि आप निश्चित हैं कि रिमोट तब बनाया गया है जब विधियाँ AIDL इंटरफ़ेस विवरण में थीं) को डिफ़ॉल्ट impl क्लास में ओवरराइड करने की आवश्यकता नहीं है।

मौजूदा एआईडीएल को संरचित/स्थिर एआईडीएल में बदलना

यदि आपके पास एक मौजूदा एआईडीएल इंटरफ़ेस और कोड है जो इसका उपयोग करता है, तो इंटरफ़ेस को स्थिर एआईडीएल इंटरफ़ेस में बदलने के लिए निम्न चरणों का उपयोग करें।

  1. अपने इंटरफ़ेस की सभी निर्भरताओं को पहचानें। प्रत्येक पैकेज के लिए इंटरफ़ेस पर निर्भर करता है, यह निर्धारित करें कि क्या पैकेज को स्थिर AIDL में परिभाषित किया गया है। यदि परिभाषित नहीं है, तो पैकेज को परिवर्तित किया जाना चाहिए।

  2. अपने इंटरफ़ेस में सभी पार्सल योग्य को स्थिर पार्सल योग्य में बदलें (इंटरफ़ेस फ़ाइलें स्वयं अपरिवर्तित रह सकती हैं)। एआईडीएल फाइलों में सीधे उनकी संरचना को व्यक्त करके ऐसा करें। इन नए प्रकारों का उपयोग करने के लिए प्रबंधन कक्षाओं को फिर से लिखा जाना चाहिए। यह आपके द्वारा aidl_interface पैकेज (नीचे) बनाने से पहले किया जा सकता है।

  3. एक aidl_interface पैकेज बनाएं (जैसा कि ऊपर वर्णित है) जिसमें आपके मॉड्यूल का नाम, इसकी निर्भरताएं और आपके लिए आवश्यक कोई अन्य जानकारी शामिल है। इसे स्थिर करने के लिए (सिर्फ संरचित नहीं), इसे संस्करणित करने की भी आवश्यकता है। अधिक जानकारी के लिए, वर्जनिंग इंटरफेस देखें।