Android प्लैटफ़ॉर्म में, कॉन्फ़िगरेशन से जुड़ा डेटा सेव करने के लिए कई एक्सएमएल फ़ाइलें होती हैं. उदाहरण के लिए, ऑडियो कॉन्फ़िगरेशन. कई एक्सएमएल फ़ाइलें vendor
पार्टिशन में हैं, लेकिन उन्हें system
पार्टीशन में पढ़ा जा सकता है. इस मामले में, एक्सएमएल फ़ाइल का स्कीमा, दोनों सेगमेंट के लिए इंटरफ़ेस के तौर पर काम करता है. इसलिए, स्कीमा को साफ़ तौर पर बताया जाना चाहिए और उसे पुराने सिस्टम के साथ काम करने वाले तरीके से अपडेट किया जाना चाहिए.
Android 10 से पहले, प्लैटफ़ॉर्म पर एक्सएमएल स्कीमा की जानकारी देने और उसका इस्तेमाल करने के लिए, कोई तरीका उपलब्ध नहीं था. साथ ही, स्कीमा में ऐसे बदलावों को रोकने के लिए भी कोई तरीका उपलब्ध नहीं था जो काम न करते. Android 10 में यह सुविधा उपलब्ध है. इसे कॉन्फ़िगरेशन फ़ाइल स्कीमा एपीआई कहा जाता है. इस तरीके में, xsdc
नाम का एक टूल और xsd_config
नाम का एक बिल्ड नियम शामिल होता है.
xsdc
टूल, एक्सएमएल स्कीमा दस्तावेज़ (XSD) कंपाइलर है. यह एक्सएमएल फ़ाइल के स्कीमा के बारे में बताने वाली XSD फ़ाइल को पार्स करता है और Java और C++ कोड जनरेट करता है. जनरेट किया गया कोड, एक्सएमएल फ़ाइलों को ऑब्जेक्ट के ट्री में पार्स करता है. ये फ़ाइलें, एक्सएसडी स्कीमा के मुताबिक होती हैं. इनमें से हर फ़ाइल, एक्सएमएल टैग का मॉडल होती है. एक्सएमएल एट्रिब्यूट को ऑब्जेक्ट के फ़ील्ड के तौर पर मॉडल किया जाता है.
xsd_config
बिल्ड नियम, xsdc
टूल को बिल्ड सिस्टम में इंटिग्रेट करता है.
किसी XSD इनपुट फ़ाइल के लिए, बिल्ड नियम Java और C++ लाइब्रेरी जनरेट करता है. लाइब्रेरी को उन मॉड्यूल से लिंक किया जा सकता है जहां एक्सएमएल फ़ाइलों को पढ़ा और इस्तेमाल किया जाता है. ये फ़ाइलें एक्सएमएल स्कीमा के मुताबिक होती हैं. system
और vendor
पार्टिशन में इस्तेमाल की जाने वाली अपनी एक्सएमएल फ़ाइलों के लिए, बिल्ड नियम का इस्तेमाल किया जा सकता है.
Build Config File Schema API
इस सेक्शन में, कॉन्फ़िगरेशन फ़ाइल स्कीमा एपीआई बनाने का तरीका बताया गया है.
Android.bp में xsd_config बिल्ड नियम को कॉन्फ़िगर करना
xsd_config
बिल्ड नियम, xsdc
टूल की मदद से पार्सर कोड जनरेट करता है. xsd_config
बिल्ड नियम की package_name
प्रॉपर्टी से, जनरेट किए गए Java कोड के पैकेज का नाम तय होता है.
xsd_config
में Android.bp
का नियम बनाने का उदाहरण:
xsd_config {
name: "hal_manifest",
srcs: ["hal_manifest.xsd"],
package_name: "hal.manifest",
}
डायरेक्ट्री स्ट्रक्चर का उदाहरण:
├── Android.bp
├── api
│ ├── current.txt
│ ├── last_current.txt
│ ├── last_removed.txt
│ └── removed.txt
└── hal_manifest.xsd
बिल्ड सिस्टम, जनरेट किए गए Java कोड का इस्तेमाल करके, एपीआई की एक सूची बनाता है और एपीआई की जांच करता है. यह एपीआई जांच, DroidCore में जोड़ी जाती है और m -j
पर लागू की जाती है.
एपीआई की सूचियों में मौजूद फ़ाइलें बनाएं
एपीआई की जांच के लिए, सोर्स कोड में एपीआई की सूची वाली फ़ाइलें ज़रूरी हैं.
एपीआई की सूची में ये फ़ाइलें शामिल हैं:
current.txt
औरremoved.txt
, एपीआई में हुए बदलावों की जांच करते हैं. इसके लिए, वे एपीआई फ़ाइलों की तुलना करते हैं जो बिल्ड के समय जनरेट होती हैं.last_current.txt
औरlast_removed.txt
, एपीआई फ़ाइलों की तुलना करके यह जांच करते हैं कि एपीआई, पहले के वर्शन के साथ काम करते हैं या नहीं.
एपीआई की सूचियों वाली फ़ाइलें बनाने के लिए:
- खाली सूचियों की फ़ाइलें बनाएं.
make update-api
निर्देश चलाएं.
जनरेट किए गए पार्स करने वाले कोड का इस्तेमाल करना
जनरेट किए गए Java कोड का इस्तेमाल करने के लिए, Java srcs
प्रॉपर्टी में xsd_config
मॉड्यूल के नाम के आगे :
जोड़ें. जनरेट किए गए Java कोड का पैकेज, package_name
प्रॉपर्टी के जैसा ही होता है.
java_library {
name: "vintf_test_java",
srcs: [
"srcs/**/*.java"
":hal_manifest"
],
}
जनरेट किए गए C++ कोड का इस्तेमाल करने के लिए, generated_sources
और generated_headers
प्रॉपर्टी में xsd_config
मॉड्यूल का नाम जोड़ें. साथ ही, static_libs
या shared_libs
में libxml2
जोड़ें, क्योंकि जनरेट किए गए पार्सर कोड में libxml2
ज़रूरी है. जनरेट किए गए C++ कोड का नेमस्पेस, package_name
प्रॉपर्टी जैसा ही होता है. उदाहरण के लिए, अगर xsd_config
मॉड्यूल का नाम hal.manifest
है, तो नेमस्पेस hal::manifest
होगा.
cc_library{
name: "vintf_test_cpp",
srcs: ["main.cpp"],
generated_sources: ["hal_manifest"],
generated_headers: ["hal_manifest"],
shared_libs: ["libxml2"],
}
पार्स करने वाले टूल का इस्तेमाल करना
Java पार्सर कोड इस्तेमाल करने के लिए, XmlParser#read
या read{class-name}
तरीके का इस्तेमाल करके, रूट एलिमेंट की क्लास दिखाएं. इस समय पार्स किया जाता है.
import hal.manifest.*;
…
class HalInfo {
public String name;
public String format;
public String optional;
…
}
void readHalManifestFromXml(File file) {
…
try (InputStream str = new BufferedInputStream(new FileInputStream(file))) {
Manifest manifest = XmlParser.read(str);
for (Hal hal : manifest.getHal()) {
HalInfo halinfo;
HalInfo.name = hal.getName();
HalInfo.format = hal.getFormat();
HalInfo.optional = hal.getOptional();
…
}
}
…
}
C++ पार्सर कोड का इस्तेमाल करने के लिए, पहले हेडर फ़ाइल शामिल करें. हेडर फ़ाइल का नाम, पैकेज का नाम होता है. इसमें बिंदु (.) को अंडरस्कोर (_) में बदल दिया जाता है.
इसके बाद, रूट एलिमेंट की क्लास लौटाने के लिए read
या read{class-name}
तरीके का इस्तेमाल करें. इस दौरान पार्सिंग की जाती है. रिटर्न वैल्यू std::optional<>
है.
include "hal_manifest.h"
…
using namespace hal::manifest
struct HalInfo {
public std::string name;
public std::string format;
public std::string optional;
…
};
void readHalManifestFromXml(std::string file_name) {
…
Manifest manifest = *read(file_name.c_str());
for (Hal hal : manifest.getHal()) {
struct HalInfo halinfo;
HalInfo.name = hal.getName();
HalInfo.format = hal.getFormat();
HalInfo.optional = hal.getOptional();
…
}
…
}
पार्स करने वाले टूल का इस्तेमाल करने के लिए दिए गए सभी एपीआई, api/current.txt
में मौजूद हैं. एक जैसा दिखने के लिए, सभी एलिमेंट और एट्रिब्यूट के नाम को कैमल केस (उदाहरण के लिए, ElementName
) में बदल दिया जाता है. साथ ही, इनका इस्तेमाल उससे जुड़े वैरिएबल, तरीके, और क्लास के नाम के तौर पर किया जाता है. पार्स किए गए रूट एलिमेंट की क्लास, read{class-name}
फ़ंक्शन का इस्तेमाल करके पाई जा सकती है. अगर सिर्फ़ एक रूट एलिमेंट है, तो फ़ंक्शन का नाम read
होगा. पार्स किए गए सब-एलिमेंट या एट्रिब्यूट की वैल्यू, get{variable-name}
फ़ंक्शन का इस्तेमाल करके ली जा सकती है.
पार्स करने वाला कोड जनरेट करना
ज़्यादातर मामलों में, आपको xsdc
को सीधे चलाने की ज़रूरत नहीं होती. इसके बजाय, xsd_config
बिल्ड नियम का इस्तेमाल करें, जैसा कि Android.bp में xsd_config बिल्ड नियम को कॉन्फ़िगर करना में बताया गया है. इस सेक्शन में, xsdc
कमांड लाइन इंटरफ़ेस के बारे में बताया गया है. यह
डीबग करने में मददगार हो सकता है.
आपको xsdc
टूल को XSD फ़ाइल का पाथ और एक पैकेज देना होगा. पैकेज, Java कोड में पैकेज का नाम और C++ कोड में नेमस्पेस है. जनरेट किया गया कोड Java है या C, यह तय करने के लिए -j
या -c
विकल्प चुनें. -o
विकल्प, आउटपुट डायरेक्ट्री का पाथ है.
usage: xsdc path/to/xsd_file.xsd [-c] [-j] [-o <arg>] [-p]
-c,--cpp Generate C++ code.
-j,--java Generate Java code.
-o,--outDir <arg> Out Directory
-p,--package Package name of the generated java file. file name of
generated C++ file and header
निर्देश का उदाहरण:
$ xsdc audio_policy_configuration.xsd -p audio.policy -j