Android platformu, yapılandırma verilerini (ör. ses yapılandırması) depolamak için birçok XML dosyası içerir. XML dosyalarının çoğu vendor
bölümündedir ancak system
bölümünde okunur. Bu durumda, XML dosyasının şeması iki bölüm arasında arayüz görevi görür. Bu nedenle, şema açıkça belirtilmeli ve geriye dönük uyumlu bir şekilde gelişmelidir.
Android 10'dan önce platform, XML şemasını belirtmeyi ve kullanmayı zorunlu kılacak veya şemada uyumsuz değişiklikleri önleyecek mekanizmalar sağlamadı. Android 10, Yapılandırma Dosyası Şeması API'si adlı bu mekanizmayı sağlar. Bu mekanizma, xsdc
adlı bir araç ve xsd_config
adlı bir derleme kuralından oluşur.
xsdc
aracı bir XML Şeması Belgesi (XSD) derleyicisidir. Bir XML dosyasının şemasını açıklayan bir XSD dosyasını ayrıştırır ve Java ile C++ kodu oluşturur. Oluşturulan kod, XSD şemasına uygun XML dosyalarını bir nesne ağacına ayrıştırır. Bu nesnelerin her biri, XML etiketi modeller. XML özellikleri, nesnelerin alanları olarak modellenir.
xsd_config
derleme kuralı, xsdc
aracını derleme sistemine entegre eder.
Belirli bir XSD giriş dosyası için derleme kuralı Java ve C++ kitaplıkları oluşturur. Kitaplıkları, XSD'ye uygun XML dosyalarının okunup kullanıldığı modüllere bağlayabilirsiniz. Derleme kuralını, system
ve vendor
bölümlerinde kullanılan kendi XML dosyalarınız için kullanabilirsiniz.
Build Config File Schema API
Bu bölümde, Yapılandırma Dosyası Şeması API'sinin nasıl oluşturulacağı açıklanmaktadır.
Android.bp dosyasında xsd_config derleme kuralını yapılandırın
xsd_config
derleme kuralı, xsdc
aracıyla ayrıştırıcı kodunu oluşturur. xsd_config
derleme kuralının package_name
mülkü, oluşturulan Java kodunun paket adını belirler.
Android.bp
'da xsd_config
derleme kuralı örneği:
xsd_config {
name: "hal_manifest",
srcs: ["hal_manifest.xsd"],
package_name: "hal.manifest",
}
Örnek dizin yapısı:
├── Android.bp
├── api
│ ├── current.txt
│ ├── last_current.txt
│ ├── last_removed.txt
│ └── removed.txt
└── hal_manifest.xsd
Derleme sistemi, oluşturulan Java kodunu kullanarak bir API listesi oluşturur ve API'yi bu listeye göre kontrol eder. Bu API kontrolü DroidCore'a eklenir ve m -j
adresinde yürütülür.
API listesi dosyaları oluşturma
API kontrolleri için API'nin kaynak kodundaki dosyaları listelemesi gerekir.
API listelerinde yer alan dosyalar:
current.txt
veremoved.txt
, derleme sırasında oluşturulan API dosyalarıyla karşılaştırma yaparak API'lerin değiştirilip değiştirilmediğini kontrol eder.last_current.txt
velast_removed.txt
, API dosyalarıyla karşılaştırarak API'lerin geriye dönük uyumlu olup olmadığını kontrol eder.
API listeleri dosyalarını oluşturmak için:
- Boş liste dosyaları oluşturun.
make update-api
komutunu çalıştırın.
Oluşturulan ayrıştırıcı kodunu kullanma
Oluşturulan Java kodunu kullanmak için Java srcs
mülkünde xsd_config
modül adına :
ön ekini ekleyin. Oluşturulan Java kodunun paketi, package_name
mülküyle aynıdır.
java_library {
name: "vintf_test_java",
srcs: [
"srcs/**/*.java"
":hal_manifest"
],
}
Oluşturulan C++ kodunu kullanmak için xsd_config
modül adını generated_sources
ve generated_headers
özelliklerine ekleyin. Oluşturulan ayrıştırıcı kodunda libxml2
gerekli olduğundan libxml2
'ü static_libs
veya shared_libs
'ye ekleyin. Oluşturulan C++ kodunun ad alanı, package_name
mülküyle aynıdır. Örneğin, xsd_config
modülü adı hal.manifest
ise ad alanı hal::manifest
olur.
cc_library{
name: "vintf_test_cpp",
srcs: ["main.cpp"],
generated_sources: ["hal_manifest"],
generated_headers: ["hal_manifest"],
shared_libs: ["libxml2"],
}
Ayrıştırıcıyı kullanma
Java ayrıştırıcı kodunu kullanmak için kök öğenin sınıfını döndürmek üzere XmlParser#read
veya read{class-name}
yöntemini kullanın. Ayrıştırma bu sırada gerçekleşir.
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++ ayrıştırıcı kodunu kullanmak için önce başlık dosyasını ekleyin. Başlık dosyasının adı, noktaların (.) alt çizgiye (_) dönüştürüldüğü paket adıdır.
Ardından, kök öğenin sınıfını döndürmek için read
veya read{class-name}
yöntemini kullanın. Ayrıştırma bu sırada gerçekleşir. Döndürülen değer bir std::optional<>
olur.
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();
…
}
…
}
Ayrıştırıcıyı kullanmak için sağlanan tüm API'ler api/current.txt
içindedir. Tekdüzelik sağlamak için tüm öğe ve özellik adları büyük/küçük harf kullanımına (ör. ElementName
) dönüştürülür ve ilgili değişken, yöntem ve sınıf adı olarak kullanılır. Ayrıştırılan kök öğenin sınıfı, read{class-name}
işlevi kullanılarak elde edilebilir. Yalnızca bir kök öğe varsa işlev adı read
olur. Ayrıştırılmış bir alt öğenin veya özelliğin değeri, get{variable-name}
işlevi kullanılarak elde edilebilir.
Ayrıştırıcı kodu oluşturma
Çoğu durumda xsdc
'ü doğrudan çalıştırmanız gerekmez. Bunun yerine, Android.bp dosyasında xsd_config derleme kuralını yapılandırma bölümünde açıklandığı gibi xsd_config
derleme kuralını kullanın. Bu bölümde, eksiksiz olması için xsdc
komut satırı arayüzü açıklanmaktadır. Bu işlem, hata ayıklama için faydalı olabilir.
xsdc
aracına XSD dosyasının yolunu ve bir paket vermeniz gerekir. Paket, Java kodunda bir paket adı, C++ kodunda ise bir ad alanıdır. Oluşturulan kodun Java mı yoksa C mi olacağını belirlemek için seçenekler sırasıyla -j
veya -c
'tır. -o
seçeneği, çıkış dizininin yoludur.
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
Örnek komut:
$ xsdc audio_policy_configuration.xsd -p audio.policy -j