แพลตฟอร์ม Android มีไฟล์ XML จำนวนมากสำหรับจัดเก็บการกำหนดค่า
(เช่น การกำหนดค่าเสียง) ไฟล์ XML หลายไฟล์อยู่ใน vendor
แต่จะอ่านในพาร์ติชัน system
ในกรณีนี้ สคีมา
ไฟล์ XML ทำหน้าที่เป็นอินเทอร์เฟซใน 2 พาร์ติชัน ดังนั้น
ต้องระบุสคีมาอย่างชัดเจนและต้องพัฒนาให้สอดคล้องกับเวอร์ชันย้อนหลัง
ลักษณะ
ก่อน Android 10 แพลตฟอร์มนี้ไม่มี
เพื่อกำหนดให้ระบุและใช้สคีมา XML หรือเพื่อป้องกัน
การเปลี่ยนแปลงที่เข้ากันไม่ได้ในสคีมา Android 10 มาพร้อมกับ
กลไกนี้ซึ่งเรียกว่า API สคีมาไฟล์การกำหนดค่า กลไกนี้ประกอบด้วยเครื่องมือ
ชื่อ xsdc
และกฎบิลด์ xsd_config
เครื่องมือ xsdc
คือคอมไพเลอร์เอกสารสคีมา XML (XSD) แยกวิเคราะห์ไฟล์ XSD
ซึ่งอธิบายสคีมาของไฟล์ XML และสร้างโค้ด Java และ C++
โค้ดที่สร้างขึ้นจะแยกวิเคราะห์ไฟล์ XML ที่สอดคล้องกับสคีมา XSD เป็นแผนผัง
แต่ละโมเดลมีโมเดลแท็ก XML แอตทริบิวต์ XML จะมีโมเดลเป็นฟิลด์
ของออบเจ็กต์
กฎของบิลด์ xsd_config
จะผสานรวมเครื่องมือ xsdc
เข้ากับระบบบิลด์
สำหรับไฟล์อินพุต XSD ที่ระบุ กฎการสร้างจะสร้างไลบรารี Java และ C++ คุณ
สามารถลิงก์ไลบรารีกับโมดูลซึ่งไฟล์ XML ที่สอดคล้องกับ
อ่านและใช้ XSD แล้ว คุณสามารถใช้กฎบิลด์สำหรับไฟล์ XML ของคุณเองที่ใช้
ในพาร์ติชัน system
และ vendor
API สคีมาไฟล์การกำหนดค่าบิลด์
ส่วนนี้จะอธิบายวิธีสร้าง API สคีมาไฟล์การกำหนดค่า
กำหนดค่ากฎบิลด์ xsd_config ใน Android.bp
กฎการสร้าง xsd_config
จะสร้างโค้ดโปรแกรมแยกวิเคราะห์ด้วยเครื่องมือ xsdc
พร็อพเพอร์ตี้ package_name
ของ xsd_config
ของกฎบิลด์จะระบุชื่อแพ็กเกจของ
โค้ด 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
ระบบบิลด์จะสร้างรายการ API โดยใช้โค้ด Java ที่สร้างขึ้นและการตรวจสอบ
API นั้นตรงกันไม่ได้ การตรวจสอบ API นี้จะเพิ่มลงใน DroidCore และดำเนินการในเวลา m -j
สร้างไฟล์รายการ API
การตรวจสอบ API จำเป็นต้องมีรายการไฟล์ API ในซอร์สโค้ด
ไฟล์รายการ API ประกอบด้วย
current.txt
และremoved.txt
ตรวจสอบว่า API มีการเปลี่ยนแปลงหรือไม่ โดยเปรียบเทียบกับไฟล์ API ที่สร้างขึ้น ณ เวลาบิลด์last_current.txt
และlast_removed.txt
ตรวจสอบว่า API มีการ ที่เข้ากันได้แบบย้อนหลัง โดยการเปรียบเทียบกับไฟล์ API
วิธีสร้างไฟล์รายการ API
- สร้างไฟล์รายการที่ว่างเปล่า
- เรียกใช้คำสั่ง
make update-api
ใช้โค้ดโปรแกรมแยกวิเคราะห์ที่สร้างขึ้น
หากต้องการใช้โค้ด Java ที่สร้างขึ้น ให้เพิ่ม :
เป็นคำนำหน้าไปยังโมดูล xsd_config
ในพร็อพเพอร์ตี้ Java srcs
แพ็กเกจของโค้ด Java ที่สร้างขึ้นคือ
เหมือนกับพร็อพเพอร์ตี้ package_name
java_library {
name: "vintf_test_java",
srcs: [
"srcs/**/*.java"
":hal_manifest"
],
}
หากต้องการใช้โค้ด C++ ที่สร้างขึ้น ให้เพิ่มชื่อโมดูล xsd_config
ลงใน
generated_sources
และพร็อพเพอร์ตี้ generated_headers
และเพิ่ม libxml2
ไปที่
static_libs
หรือ shared_libs
เนื่องจากต้องใช้ 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 ทั้งหมดที่ระบุให้ใช้โปรแกรมแยกวิเคราะห์อยู่ใน api/current.txt
สำหรับ
แบบเดียวกัน ชื่อองค์ประกอบและแอตทริบิวต์ทั้งหมดจะถูกแปลงเป็นตัวพิมพ์อูฐ (สำหรับ
เช่น ElementName
) และใช้เป็นตัวแปร เมธอด และ
ชื่อชั้นเรียน คลาสขององค์ประกอบรากที่แยกวิเคราะห์แล้วสามารถหาได้โดยใช้ฟังก์ชัน
read{class-name}
หากมีเพียงรูทเดียว
ชื่อฟังก์ชันจะเป็น read
ค่าขององค์ประกอบย่อยที่แยกวิเคราะห์แล้ว หรือ
รับแอตทริบิวต์ได้โดยใช้ get{variable-name}
สร้างโค้ดโปรแกรมแยกวิเคราะห์
ในกรณีส่วนใหญ่ คุณไม่จำเป็นต้องเรียกใช้ xsdc
โดยตรง ใช้บิลด์ xsd_config
แทน ตามที่อธิบายไว้ใน
การกำหนดค่ากฎบิลด์ xsd_config ใน Android.bp ช่วงเวลานี้
ส่วนนี้จะอธิบายอินเทอร์เฟซบรรทัดคำสั่ง xsdc
เพื่อความครบถ้วนสมบูรณ์ ช่วงเวลานี้
อาจเป็นประโยชน์ในการแก้ไขข้อบกพร่อง
คุณต้องกำหนดเส้นทางไปยังไฟล์ XSD และแพ็กเกจให้เครื่องมือ xsdc
แพ็กเกจคือชื่อแพ็กเกจในโค้ด 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