يحتوي نظام Android الأساسي على العديد من ملفات XML لتخزين بيانات الضبط (مثل إعدادات الصوت). تقع العديد من ملفات XML في القسم vendor
، ولكن يتم قراءتها في القسم system
. في هذه الحالة، يُعدّ المخطّط
لملف XML بمثابة الواجهة بين القسمَين، وبالتالي πρέπει
تحديد المخطّط صراحةً ويجب تطويره بطريقة متوافقة مع الإصدارات السابقة.
قبل الإصدار 10 من Android، لم توفّر المنصة mekanismes لطلب تحديد مخطّط XML واستخدامه، أو لمنع التغيُّرات غير المتوافقة في المخطّط. يقدّم نظام التشغيل Android 10
هذه الآلية التي تُعرف باسم Config File Schema API. تتألف هذه الآلية من أداة
تُسمى xsdc
وقاعدة إنشاء تُسمى xsd_config
.
أداة xsdc
هي أداة تجميع لمستند مخطّط XML (XSD). وهي تُحلِّل ملف XSD
الذي يصف مخطّط ملف XML وتُنشئ رمز Java وC++. يُحلِّل الرمز المبرمَج
المُنشئ ملفات XML المتوافقة مع مخطّط XSD إلى شجرة من
العناصر، يمثّل كلّ منها علامة XML. يتم وضع سمات XML في حقول
الكائنات.
تدمج قاعدة الإنشاء xsd_config
أداة xsdc
في نظام الإنشاء.
بالنسبة إلى ملف إدخال XSD معيّن، تنشئ قاعدة الإنشاء مكتبتَي Java وC++. يمكنك
ربط المكتبات بالوحدات التي يتم فيها قراءة ملفات XML المتوافقة مع schemaDTD واستخدامها. يمكنك استخدام قاعدة الإنشاء لملفات XML الخاصة بك المستخدَمة
في قسمَي system
وvendor
.
Build Config File Schema API
يوضّح هذا القسم كيفية إنشاء واجهة برمجة التطبيقات Config File Schema 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
يُنشئ نظام الإنشاء قائمة بواجهة برمجة التطبيقات باستخدام رمز Java الذي تم إنشاؤه ويتحقّق من واجهة برمجة التطبيقات. تتم إضافة عملية التحقّق من واجهة برمجة التطبيقات هذه إلى DroidCore ويتم تنفيذها في m -j
.
إنشاء ملفات قوائم واجهات برمجة التطبيقات
تتطلّب عمليات التحقّق من واجهة برمجة التطبيقات أن تُدرِج واجهة برمجة التطبيقات الملفات في رمز المصدر.
تشمل قائمة واجهة برمجة التطبيقات الملفات التالية:
- يتحقّق
current.txt
وremoved.txt
ممّا إذا تم تغيير واجهات برمجة التطبيقات من خلال مقارنة ملفات واجهات برمجة التطبيقات التي تم إنشاؤها في وقت الإنشاء. - يتحقق
last_current.txt
وlast_removed.txt
مما إذا كانت واجهات برمجة التطبيقات متوافقة مع الإصدارات القديمة من خلال المقارنة مع ملفات واجهات برمجة التطبيقات.
لإنشاء ملفات قوائم واجهات برمجة التطبيقات:
- أنشئ ملفات قوائم فارغة.
- نفِّذ الأمر
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/current.txt
. من أجل
الاتساق، يتم تحويل جميع أسماء العناصر والسمات إلى كتابة الجمل بالتنسيق اللاتيني (مثل
ElementName
) واستخدامها كسمة المتغيّر والطريقة
واسم الفئة المقابلَين. يمكن الحصول على فئة العنصر الجذر الذي تم تحليله باستخدام الدالة
read{class-name}
. إذا كان هناك عنصر جذر واحد فقط، يكون اسم الدالة هو read
. يمكن الحصول على قيمة عنصر فرعي أو
سمة تم تحليلهما باستخدام الدالة get{variable-name}
.
إنشاء رمز المُحلِّل
في معظم الحالات، ليس عليك تشغيل xsdc
مباشرةً. استخدِم قاعدة الإنشاء xsd_config
بدلاً من ذلك، كما هو موضّح في
ضبط قاعدة الإنشاء xsd_config في Android.bp. يوضّح
هذا القسم واجهة سطر الأوامر 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