Java SDK लाइब्रेरी लागू करना

Android प्लैटफ़ॉर्म में, शेयर की गई बड़ी संख्या में Java लाइब्रेरी मौजूद होती हैं. इन्हें ऐप्लिकेशन के मेनिफ़ेस्ट में <uses-library> टैग के साथ, ऐप्लिकेशन के क्लासपाथ में शामिल किया जा सकता है. हालांकि, ऐसा करना ज़रूरी नहीं है. ऐप्लिकेशन इन लाइब्रेरी के साथ लिंक होते हैं. इसलिए, इन लाइब्रेरी को काम करने के साथ-साथ, एपीआई की समीक्षा और टूल के लिए सहायता के मामले में, बाकी Android एपीआई की तरह ही माना जाता है. हालांकि, ध्यान दें कि ज़्यादातर लाइब्रेरी में ये सुविधाएं नहीं होती हैं.

java_sdk_library मॉड्यूल टाइप, इस तरह की लाइब्रेरी मैनेज करने में मदद करता है. डिवाइस बनाने वाली कंपनियां, अपने एपीआई के लिए पुराने सिस्टम के साथ काम करने की सुविधा बनाए रखने के लिए, अपनी शेयर की गई Java लाइब्रेरी के लिए इस तरीके का इस्तेमाल कर सकती हैं. अगर डिवाइस बनाने वाली कंपनियां, बूटक्लास पाथ के बजाय <uses-library> टैग के ज़रिए अपनी शेयर की गई Java लाइब्रेरी का इस्तेमाल करती हैं, तो java_sdk_library इस बात की पुष्टि कर सकता है कि वे Java लाइब्रेरी, एपीआई के हिसाब से सही हैं.

java_sdk_library, ऐप्लिकेशन के इस्तेमाल के लिए वैकल्पिक SDK टूल के एपीआई लागू करता है. आपकी बिल्ड फ़ाइल (Android.bp) में java_sdk_library के ज़रिए लागू की गई लाइब्रेरी, ये कार्रवाइयां करती हैं:

  • स्टब लाइब्रेरी, stubs, stubs.system, और stubs.test को शामिल करने के लिए जनरेट की जाती हैं. ये स्टब लाइब्रेरी, @hide, @SystemApi, और @TestApi एनोटेशन की पहचान करके बनाई जाती हैं.
  • java_sdk_library, एपीआई की सबडायरेक्ट्री में एपीआई स्पेसिफ़िकेशन फ़ाइलों (जैसे कि current.txt) को मैनेज करता है. इन फ़ाइलों की जांच, सबसे नए कोड के साथ की जाती है, ताकि यह पक्का किया जा सके कि ये फ़ाइलें सबसे नए वर्शन हैं. अगर ऐसा नहीं होता है, तो आपको गड़बड़ी का एक मैसेज मिलेगा. इसमें, उन्हें अपडेट करने का तरीका बताया जाएगा. अपडेट में किए गए सभी बदलावों की मैन्युअल तौर पर समीक्षा करें, ताकि यह पक्का किया जा सके कि वे आपकी उम्मीदों के मुताबिक हैं.

    सभी एपीआई को अपडेट करने के लिए, m update-api का इस्तेमाल करें. यह पुष्टि करने के लिए कि कोई एपीआई अप-टू-डेट है या नहीं, m checkapi का इस्तेमाल करें.
  • एपीआई की खास जानकारी वाली फ़ाइलों की जांच, हाल ही में पब्लिश किए गए Android वर्शन के साथ की जाती है. इससे यह पक्का किया जाता है कि एपीआई, पुराने वर्शन के साथ काम करता है. AOSP के हिस्से के तौर पर दिए गए java_sdk_library मॉड्यूल, पहले रिलीज़ किए गए अपने वर्शन को prebuilts/sdk/<latest number> में डालते हैं.
  • एपीआई स्पेसिफ़िकेशन फ़ाइलों की जांच के लिए, इनमें से किसी एक काम को किया जा सकता है:
    • जांच जारी रखने की अनुमति दें. (कुछ न करें.)
    • java_sdk_library में यह जोड़कर, जांच बंद करें:
      unsafe_ignore_missing_latest_api: true,
    • version/scope/api डायरेक्ट्री में module_name.txt नाम की खाली टेक्स्ट फ़ाइलें बनाकर, नए java_sdk_library मॉड्यूल के लिए खाली एपीआई उपलब्ध कराएं.
  • अगर रनटाइम के लिए लागू करने की लाइब्रेरी इंस्टॉल है, तो एक एक्सएमएल फ़ाइल जनरेट और इंस्टॉल हो जाती है.

java_sdk_library कैसे काम करती है

X नाम का java_sdk_library, ये बनाता है:

  1. लागू करने की लाइब्रेरी की दो कॉपी: एक लाइब्रेरी का नाम X और दूसरी का नाम X.impl है. डिवाइस पर लाइब्रेरी X इंस्टॉल हो. लाइब्रेरी X.impl सिर्फ़ तब मौजूद होती है, जब दूसरे मॉड्यूल को लागू करने वाली लाइब्रेरी का ऐक्सेस ज़रूरी हो. जैसे, टेस्टिंग में इस्तेमाल करने के लिए. ध्यान दें कि साफ़ तौर पर ऐक्सेस करने की ज़रूरत बहुत कम होती है.
  2. ऐक्सेस को पसंद के मुताबिक बनाने के लिए, स्कोप को चालू और बंद किया जा सकता है. (Java के कीवर्ड-ऐक्सेस मॉडिफ़ायर की तरह ही, सार्वजनिक दायरा कई तरह का ऐक्सेस देता है; टेस्ट दायरे में सिर्फ़ ऐसे एपीआई होते हैं जिनका इस्तेमाल टेस्टिंग में किया जाता है.) चालू किए गए हर स्कोप के लिए, लाइब्रेरी ये चीज़ें बनाती है:
    • स्टब सोर्स मॉड्यूल (droidstubs मॉड्यूल टाइप का) - लागू करने के सोर्स का इस्तेमाल करता है और एपीआई स्पेसिफ़िकेशन फ़ाइल के साथ-साथ स्टब सोर्स का एक सेट आउटपुट करता है.
    • स्टब लाइब्रेरी (java_library मॉड्यूल टाइप की) - यह स्टब का संकलित वर्शन है. इसे कंपाइल करने के लिए इस्तेमाल की गई लाइब्रेरी, java_sdk_library को दी गई लाइब्रेरी से अलग होती हैं. इससे यह पक्का होता है कि एपीआई स्टब में, लागू करने की जानकारी लीक न हो.
    • अगर आपको स्टब को कंपाइल करने के लिए अन्य लाइब्रेरी की ज़रूरत है, तो उन्हें उपलब्ध कराने के लिए stub_only_libs और stub_only_static_libs प्रॉपर्टी का इस्तेमाल करें.

अगर किसी java_sdk_library को “X” कहा जाता है और उसे “X” के तौर पर संकलित किया जा रहा है, तो हमेशा उसी नाम से रेफ़र करें और उसमें बदलाव न करें. बिल्डर, सही लाइब्रेरी चुन लेगा. यह पक्का करने के लिए कि आपके पास सबसे सही लाइब्रेरी है, अपने स्टब की जांच करें. इससे यह पता चलेगा कि बिल्ड में कोई गड़बड़ी तो नहीं हुई है. इस दिशा-निर्देश का इस्तेमाल करके, ज़रूरी बदलाव करें:

  • कमांड-लाइन पर जाकर पुष्टि करें कि आपके पास सही लाइब्रेरी है. साथ ही, अपने दायरे का पता लगाने के लिए, देखें कि वहां कौनसे स्टब मौजूद हैं:
    • स्कोप काफ़ी बड़ा है: जिस लाइब्रेरी पर निर्भर किया जा रहा है उसे एपीआई के किसी खास स्कोप की ज़रूरत है. हालांकि, आपको लाइब्रेरी में ऐसे एपीआई दिखते हैं जो उस दायरे से बाहर के होते हैं. जैसे, सार्वजनिक एपीआई के साथ शामिल सिस्टम एपीआई.
    • स्कोप बहुत छोटा है: डिपेंडेंट लाइब्रेरी के पास सभी ज़रूरी लाइब्रेरी का ऐक्सेस नहीं है. उदाहरण के लिए, डिपेंडेंट लाइब्रेरी को सिस्टम एपीआई का इस्तेमाल करना चाहिए, लेकिन उसे सार्वजनिक एपीआई मिलता है. आम तौर पर, इससे संकलन से जुड़ी गड़बड़ी होती है, क्योंकि ज़रूरी एपीआई मौजूद नहीं होते.
  • लाइब्रेरी को ठीक करने के लिए, इनमें से सिर्फ़ एक तरीका अपनाएं:
    • अपनी ज़रूरत के हिसाब से वर्शन चुनने के लिए, sdk_version बदलें. या
    • सही लाइब्रेरी के बारे में साफ़ तौर पर बताएं, जैसे कि <X>.stubs या <X>.stubs.system.

java_sdk_library X का इस्तेमाल

लागू करने की लाइब्रेरी X का इस्तेमाल तब किया जाता है, जब उसका रेफ़रंस apex.java_libs से दिया जाता है. हालांकि, Soong की एक सीमा के कारण, जब लाइब्रेरी X का रेफ़रंस, एक ही APEX लाइब्रेरी में मौजूद किसी दूसरे java_sdk_library मॉड्यूल से दिया जाता है, तो लाइब्रेरी X के बजाय X.impl का साफ़ तौर पर इस्तेमाल किया जाना चाहिए.

जब java_sdk_library का रेफ़रंस किसी दूसरी जगह से दिया जाता है, तो स्टब लाइब्रेरी का इस्तेमाल किया जाता है. स्टब लाइब्रेरी, डिपेंडेंट मॉड्यूल की sdk_version प्रॉपर्टी सेटिंग के हिसाब से चुनी जाती है. उदाहरण के लिए, sdk_version: "current" का इस्तेमाल करने वाला मॉड्यूल, सार्वजनिक स्टब का इस्तेमाल करता है, जबकि sdk_version: "system_current" का इस्तेमाल करने वाला मॉड्यूल, सिस्टम स्टब का इस्तेमाल करता है. अगर एग्ज़ैक्ट मैच नहीं मिलता है, तो सबसे मिलती-जुलती स्टब लाइब्रेरी का इस्तेमाल किया जाता है. सिर्फ़ सार्वजनिक एपीआई उपलब्ध कराने वाला java_sdk_library, सभी के लिए सार्वजनिक स्टब उपलब्ध कराएगा.

Java SDK लाइब्रेरी की मदद से फ़्लो बनाना
पहली इमेज. Java SDK लाइब्रेरी की मदद से फ़्लो बनाना

उदाहरण और सोर्स

srcs और api_packages प्रॉपर्टी, java_sdk_library में मौजूद होनी चाहिए.

java_sdk_library {
        name: "com.android.future.usb.accessory",
        srcs: ["src/**/*.java"],
        api_packages: ["com.android.future.usb"],
    }

AOSP का सुझाव है कि नए java_sdk_library इंस्टेंस, उन एपीआई स्कोप को साफ़ तौर पर चालू करें जिनका उन्हें इस्तेमाल करना है. हालांकि, ऐसा करना ज़रूरी नहीं है. आपके पास, मौजूदा java_sdk_library इंस्टेंस को माइग्रेट करने का विकल्प भी है, ताकि वे एपीआई स्कोप साफ़ तौर पर चालू कर सकें जिनका इस्तेमाल किया जाएगा:

java_sdk_library {
         name: "lib",
         public: {
           enabled: true,
         },
         system: {
           enabled: true,
         },
         
    }

रनटाइम के लिए इस्तेमाल की जाने वाली impl लाइब्रेरी को कॉन्फ़िगर करने के लिए, hostdex, compile_dex, और errorprone जैसी सभी सामान्य java_library प्रॉपर्टी का इस्तेमाल करें.

java_sdk_library {
        name: "android.test.base",

        srcs: ["src/**/*.java"],

        errorprone: {
          javacflags: ["-Xep:DepAnn:ERROR"],
        },

        hostdex: true,

        api_packages: [
            "android.test",
            "android.test.suitebuilder.annotation",
            "com.android.internal.util",
            "junit.framework",
        ],

        compile_dex: true,
    }

स्टब लाइब्रेरी कॉन्फ़िगर करने के लिए, इन प्रॉपर्टी का इस्तेमाल करें:

  • merge_annotations_dirs और merge_inclusion_annotations_dirs.
  • api_srcs: ज़रूरी नहीं वाली सोर्स फ़ाइलों की सूची, जो एपीआई का हिस्सा हैं, लेकिन रनटाइम लाइब्रेरी का हिस्सा नहीं हैं.
  • stubs_only_libs: स्टब बनाते समय, क्लासपाथ में मौजूद Java लाइब्रेरी की सूची.
  • hidden_api_packages: पैकेज के उन नामों की सूची जिन्हें एपीआई से छिपाना ज़रूरी है.
  • droiddoc_options: metalava के लिए अतिरिक्त आर्ग्युमेंट.
  • droiddoc_option_files: उन फ़ाइलों की सूची दिखाता है जिनका रेफ़रंस, $(location <label>) का इस्तेमाल करके droiddoc_options में दिया जा सकता है. यहां <file>, सूची में मौजूद एक एंट्री है.
  • annotations_enabled.

java_sdk_library एक java_library है, लेकिन यह droidstubs मॉड्यूल नहीं है. इसलिए, यह droidstubs की सभी प्रॉपर्टी के साथ काम नहीं करता. यह उदाहरण, android.test.mock library build फ़ाइल से लिया गया है.

java_sdk_library {
        name: "android.test.mock",

        srcs: [":android-test-mock-sources"],
        api_srcs: [
            // Note: The following aren’t APIs of this library. Only APIs under the
            // android.test.mock package are taken. These do provide private APIs
            // to which android.test.mock APIs reference. These classes are present
            // in source code form to access necessary comments that disappear when
            // the classes are compiled into a Jar library.
            ":framework-core-sources-for-test-mock",
            ":framework_native_aidl",
        ],

        libs: [
            "framework",
            "framework-annotations-lib",
            "app-compat-annotations",
            "Unsupportedappusage",
        ],

        api_packages: [
            "android.test.mock",
        ],
        permitted_packages: [
            "android.test.mock",
        ],
        compile_dex: true,
        default_to_stubs: true,
    }

पुराने सिस्टम के साथ काम करने की सुविधा बनाए रखना

बिल्ड सिस्टम यह जांच करता है कि एपीआई, बिल्ड के समय जनरेट की गई एपीआई फ़ाइलों के साथ काम करते हैं या नहीं. इसके लिए, वह नई एपीआई फ़ाइलों की तुलना जनरेट की गई एपीआई फ़ाइलों से करता है. java_sdk_library, prebuilt_apis की दी गई जानकारी का इस्तेमाल करके, काम करने की जांच करता है. java_sdk_library का इस्तेमाल करके बनाई गई सभी लाइब्रेरी में, prebuilt_apis में api_dirs के नए वर्शन में एपीआई फ़ाइलें होनी चाहिए. वर्शन रिलीज़ करने पर, एपीआई की सूची वाली फ़ाइलें और स्टब लाइब्रेरी, PRODUCT=sdk_phone_armv7-sdk के साथ डिस्ट्रिब्यूशन बिल्ड की मदद से हासिल की जा सकती हैं.

api_dirs प्रॉपर्टी, prebuilt_apis में एपीआई वर्शन डायरेक्ट्री की सूची है. एपीआई वर्शन डायरेक्ट्री, Android.bp डायरेक्ट्री लेवल पर होनी चाहिए.

prebuilt_apis {
       name: "foo",
       api_dirs: [
           "1",
           "2",
             ....
           "30",
           "current",
       ],
    }

पहले से बनी डायरेक्ट्री में, version/scope/api/ स्ट्रक्चर के साथ डायरेक्ट्री कॉन्फ़िगर करें. version एपीआई लेवल से जुड़ा होता है और scope से यह तय होता है कि डायरेक्ट्री सार्वजनिक, सिस्टम या टेस्ट है.

  • version/scope में Java लाइब्रेरी शामिल हैं.
  • version/scope/api में एपीआई .txt फ़ाइलें मौजूद हैं. यहां module_name.txt और module_name-removed.txt नाम वाली खाली टेक्स्ट फ़ाइलें बनाएं.
     ├── 30
             ├── public
                ├── api
                   ├── android.test.mock-removed.txt
                   └── android.test.mock.txt
                └── android.test.mock.jar
             ├── system
                ├── api
                   ├── android.test.mock-removed.txt
                   └── android.test.mock.txt
                └── android.test.mock.jar
             └── test
                 ├── api
                    ├── android.test.mock-removed.txt
                    └── android.test.mock.txt
                 └── android.test.mock.jar
          └── Android.bp