Android 10 เพิ่มการรองรับอินเทอร์เฟซ Android ที่เสถียร Definition Language (AIDL) เป็นวิธีใหม่สำหรับการติดตามโปรแกรมแอปพลิเคชัน Interface (API) และ Application Bin Interface (ABI) ที่ AIDL ให้บริการ อินเทอร์เฟซ AIDL เวอร์ชันเสถียรทํางานเหมือนกับ AIDL แต่ระบบบิลด์จะติดตาม ความเข้ากันได้ของอินเทอร์เฟซ และยังมีข้อจำกัดเกี่ยวกับสิ่งที่คุณทำได้
- อินเทอร์เฟซจะกำหนดไว้ในระบบบิลด์ด้วย
aidl_interfaces
- อินเทอร์เฟซมีได้เฉพาะข้อมูลที่มีโครงสร้าง พาร์เซลที่แสดงถึง ระบบจะสร้างประเภทที่ต้องการโดยอัตโนมัติตามคำจำกัดความของ AIDL และ จะได้รับการสร้างเป็นมาร์ชาและแยกออกจากกันโดยอัตโนมัติ
- อินเทอร์เฟซอาจประกาศได้ว่าเสถียร (เข้ากันได้แบบย้อนหลัง) เมื่อใด เกิดขึ้น API จะได้รับการติดตามและกำหนดเวอร์ชันในไฟล์ข้าง AIDL ของ Google
AIDL แบบมีโครงสร้างกับแบบเสถียร
AIDL ที่มีโครงสร้างหมายถึงประเภทที่กำหนดไว้ใน AIDL เพียงอย่างเดียว ตัวอย่างเช่น การประกาศแบบพาร์เซล (พาร์เซลที่กำหนดเอง) ไม่ใช่ AIDL แบบมีโครงสร้าง พาร์เซล ซึ่งมีฟิลด์ที่กําหนดไว้ใน AIDL จะเรียกว่าพัสดุที่มีโครงสร้าง
AIDL เวอร์ชันเสถียรต้องใช้ AIDL ที่มีโครงสร้างเพื่อให้ระบบบิลด์และคอมไพเลอร์
สามารถทราบว่าการเปลี่ยนแปลงที่ทำกับพาร์เซลนั้นเข้ากันได้แบบย้อนหลังหรือไม่
อย่างไรก็ตาม อินเทอร์เฟซที่มีโครงสร้างบางรายการอาจไม่เสถียร เพื่อให้มีความเสถียร
อินเทอร์เฟซต้องใช้ประเภทที่มีโครงสร้างเท่านั้น และยังต้องใช้
การกำหนดเวอร์ชัน ในทางกลับกัน อินเทอร์เฟซจะไม่เสถียรหากบิลด์หลัก
จะใช้ระบบในการสร้างหรือเมื่อมีการตั้งค่า unstable:true
ไว้
กำหนดอินเทอร์เฟซ AIDL
คำจำกัดความของ aidl_interface
มีลักษณะดังนี้
aidl_interface {
name: "my-aidl",
srcs: ["srcs/aidl/**/*.aidl"],
local_include_dir: "srcs/aidl",
imports: ["other-aidl"],
versions_with_info: [
{
version: "1",
imports: ["other-aidl-V1"],
},
{
version: "2",
imports: ["other-aidl-V3"],
}
],
stability: "vintf",
backend: {
java: {
enabled: true,
platform_apis: true,
},
cpp: {
enabled: true,
},
ndk: {
enabled: true,
},
rust: {
enabled: true,
},
},
}
name
: ชื่อของโมดูลอินเทอร์เฟซ AIDL ที่ระบุ อินเทอร์เฟซ AIDLsrcs
: รายการไฟล์ต้นทางของ AIDL ที่เขียนอินเทอร์เฟซ เส้นทาง สำหรับ AIDL ประเภทFoo
ที่กำหนดไว้ในแพ็กเกจcom.acme
ควรอยู่ที่<base_path>/com/acme/Foo.aidl
โดยที่<base_path>
เป็นไดเรกทอรีใดก็ได้ เกี่ยวข้องกับไดเรกทอรีที่Android.bp
อยู่ ในตัวอย่างก่อนหน้านี้<base_path>
คือsrcs/aidl
local_include_dir
: เส้นทางจากจุดเริ่มต้นของชื่อแพ็กเกจ ทั้งนี้ สอดคล้องกับ<base_path>
ที่อธิบายไว้ข้างต้นimports
: รายการaidl_interface
โมดูลที่ใช้ หากหนึ่งใน อินเทอร์เฟซ AIDL ใช้อินเทอร์เฟซหรือพาร์เซลจากอินเทอร์เฟซอื่นaidl_interface
ใส่ชื่อที่นี่ ซึ่งอาจจะมีชื่อได้แค่นี้ เพื่ออ้างอิงถึงการอัปเดตล่าสุด เวอร์ชัน หรือชื่อที่มีคำต่อท้ายเวอร์ชัน (เช่น-V1
) เพื่ออ้างถึง เวอร์ชันที่เจาะจง รองรับการระบุเวอร์ชันตั้งแต่ Android 12versions
: อินเทอร์เฟซเวอร์ชันก่อนหน้าที่ ค้างที่api_dir
เริ่มต้นใน Android 11versions
มีราคาต่ำกว่าaidl_api/name
หากไม่มีเวอร์ชันใดที่หยุดนิ่งของอินเทอร์เฟซ ไม่ควรระบุข้อมูลนี้และจะไม่มีการตรวจสอบความเข้ากันได้ ช่องนี้ได้แทนที่ด้วยversions_with_info
สำหรับ Android แล้ว 13 ปีขึ้นไปversions_with_info
: รายการทูเปิ้ล แต่ละรายการมีชื่อของ เวอร์ชันที่ตรึงไว้และรายการที่มีการนำเข้าเวอร์ชันของ aidl_interface อื่นๆ โมดูลที่ aidl_interface เวอร์ชันนี้นำเข้ามา คำจำกัดความ ของเวอร์ชัน V ของอินเทอร์เฟซ AIDL อยู่ที่ IFACEaidl_api/IFACE/V
ช่องนี้เปิดตัวใน Android 13 และไม่ควรได้รับการแก้ไขในAndroid.bp
โดยตรง ช่องนี้คือ เพิ่มหรืออัปเดตโดยการเรียกใช้*-update-api
หรือ*-freeze-api
นอกจากนี้ ระบบจะย้ายข้อมูลversions
ช่องไปยังversions_with_info
โดยอัตโนมัติ เมื่อผู้ใช้เรียกใช้*-update-api
หรือ*-freeze-api
stability
: ธงที่ไม่บังคับเพื่อรับประกันความเสถียรของอินเทอร์เฟซนี้ ฟีเจอร์นี้รองรับเฉพาะ"vintf"
หากไม่ได้ตั้งค่าstability
ไว้ บิลด์ ระบบจะตรวจสอบว่าอินเทอร์เฟซสามารถใช้งานร่วมกันได้แบบย้อนหลัง เว้นแต่ว่า ระบุunstable
แล้ว การไม่ได้ตั้งค่าจะสอดคล้องกับอินเทอร์เฟซที่มี ความเสถียรในบริบทการรวบรวมนี้ (เช่น ทุกอย่างเกี่ยวกับระบบ ตัวอย่างเช่น สิ่งต่างๆ ในsystem.img
และพาร์ติชันที่เกี่ยวข้อง หรือผู้ให้บริการทั้งหมด เช่น สิ่งต่างๆ ในvendor.img
และพาร์ติชันที่เกี่ยวข้อง) ถ้าstability
ได้รับการตั้งค่าเป็น"vintf"
ซึ่งสอดคล้องกับสัญญาด้านความเสถียร: อินเทอร์เฟซต้องเสถียรตราบเท่าที่ใช้งานgen_trace
: ธงที่ไม่บังคับสำหรับเปิดหรือปิดการติดตาม จะเริ่มต้นใน Android 14 ค่าเริ่มต้นคือtrue
สำหรับcpp
และ แบ็กเอนด์java
host_supported
: แฟล็กที่ไม่บังคับซึ่งเมื่อตั้งค่าเป็นtrue
จะทำให้ ไลบรารีที่สร้างขึ้นที่พร้อมใช้งานในสภาพแวดล้อมของโฮสต์unstable
: ค่าสถานะที่ไม่บังคับซึ่งใช้ในการทำเครื่องหมายว่าอินเทอร์เฟซนี้ไม่ได้ ต้องเสถียรแล้ว เมื่อตั้งค่าเป็นtrue
ระบบของบิลด์จะไม่ สร้างไฟล์ Dump ของ API สำหรับอินเทอร์เฟซและไม่ต้องมีการอัปเดตfrozen
: แฟล็กที่ไม่บังคับซึ่งเมื่อตั้งค่าเป็นtrue
หมายความว่าอินเทอร์เฟซ ไม่มีการเปลี่ยนแปลงใดๆ นับตั้งแต่อินเทอร์เฟซเวอร์ชันก่อนหน้า วิธีนี้ช่วยให้ การตรวจสอบเวลาบิลด์ที่มากขึ้น เมื่อตั้งค่าเป็นfalse
หมายความว่าอินเทอร์เฟซอยู่ใน และมีการเปลี่ยนแปลงใหม่ๆ ดังนั้นการเรียกใช้foo-freeze-api
จะสร้าง เวอร์ชันใหม่แล้วเปลี่ยนค่าเป็นtrue
โดยอัตโนมัติ เปิดตัวใน Android 14backend.<type>.enabled
: แฟล็กเหล่านี้จะสลับแบ็กเอนด์แต่ละรายการที่ คอมไพเลอร์ AIDL จะสร้างโค้ดให้ แบ็กเอนด์ 4 รายการ รองรับ Java, C++, NDK และ Rust เปิดใช้แบ็กเอนด์ Java, C++ และ NDK โดยค่าเริ่มต้น หากไม่จำเป็นต้องใช้แบ็กเอนด์ 3 รายการนี้ ปิดใช้อย่างชัดแจ้ง Rust จะปิดใช้โดยค่าเริ่มต้นจนถึง Android 15.backend.<type>.apex_available
: รายการชื่อ APEX ที่สร้างขึ้น มีให้บริการสำหรับ Stub Librarybackend.[cpp|java].gen_log
: แฟล็กที่ไม่บังคับซึ่งควบคุมว่าจะ สร้างโค้ดเพิ่มเติมสำหรับรวบรวมข้อมูลเกี่ยวกับธุรกรรมbackend.[cpp|java].vndk.enabled
: แฟล็กที่ไม่บังคับสำหรับการสร้างอินเทอร์เฟซนี้ ส่วนหนึ่งของ VNDK ค่าเริ่มต้นคือfalse
backend.[cpp|ndk].additional_shared_libraries
: เปิดตัวใน Android 14 แฟล็กนี้จะเพิ่มทรัพยากร Dependency ไปยัง ไลบรารีแบบเนทีฟ การตั้งค่าสถานะนี้มีประโยชน์กับndk_header
และcpp_header
backend.java.sdk_version
: แฟล็กที่ไม่บังคับสำหรับระบุเวอร์ชัน ของ SDK ที่ใช้สร้างไลบรารี Java Stub ขึ้น ค่าเริ่มต้นคือ"system_current"
ไม่ควรตั้งค่าตัวเลือกนี้เมื่อbackend.java.platform_apis
มีค่าเป็นtrue
backend.java.platform_apis
: แฟล็กที่ไม่บังคับที่ควรตั้งค่าเป็นtrue
เมื่อไลบรารีที่สร้างขึ้นต้องสร้างเทียบกับ API ของแพลตฟอร์ม แทนที่จะเป็น SDK
สำหรับชุดค่าผสมของเวอร์ชันและแบ็กเอนด์ที่เปิดใช้แต่ละรายการ สตับ สร้างไลบรารีแล้ว สําหรับวิธีอ้างถึงเวอร์ชันที่เจาะจงของไลบรารี Stub สำหรับแบ็กเอนด์ที่เฉพาะเจาะจง โปรดดูกฎการตั้งชื่อโมดูล
เขียนไฟล์ AIDL
อินเทอร์เฟซใน AIDL เวอร์ชันเสถียรจะคล้ายกับอินเทอร์เฟซแบบดั้งเดิม โดย มีข้อยกเว้นว่าไม่ได้รับอนุญาตให้ใช้ที่ดินที่ไม่มีโครงสร้าง (เนื่องจาก ไม่เสถียร! ดู ที่มีโครงสร้างกับแบบเสถียร AIDL) ความแตกต่างหลักๆ ใน AIDL แบบคงที่คือ ที่มีการกำหนดพาร์เซล ก่อนหน้านี้ไฟล์พาร์เซลมีการประกาศการส่งต่อ ใน AIDL เวอร์ชันเสถียร (และแบบมีโครงสร้าง) ฟิลด์และตัวแปรที่พาร์เซล ที่กำหนดไว้อย่างชัดแจ้ง
// in a file like 'some/package/Thing.aidl'
package some.package;
parcelable SubThing {
String a = "foo";
int b;
}
ระบบรองรับค่าเริ่มต้น (แต่ไม่บังคับ) สำหรับ boolean
, char
float
, double
, byte
, int
, long
และ String
ใน Android
12 ค่าเริ่มต้นสำหรับการแจงนับที่กำหนดโดยผู้ใช้คือ
ที่รองรับ เมื่อไม่ได้ระบุค่าเริ่มต้น ระบบจะใช้ค่าที่เหมือน 0 หรือว่างเปล่า
การแจงนับที่ไม่มีค่าเริ่มต้นจะเริ่มต้นเป็น 0 แม้ว่าจะมี
ไม่มีตัวแจกแจงเป็นศูนย์
ใช้ไลบรารีต้นขั้ว
หลังจากเพิ่มไลบรารีต้นขั้วเป็นทรัพยากร Dependency ของโมดูลแล้ว
สามารถใส่ไว้ในไฟล์ของคุณได้ ต่อไปนี้เป็นตัวอย่างของไลบรารีสตับใน
ระบบบิลด์ (Android.mk
สามารถใช้สำหรับคำนิยามโมดูลเดิมได้ด้วย):
cc_... {
name: ...,
shared_libs: ["my-module-name-cpp"],
...
}
# or
java_... {
name: ...,
// can also be shared_libs if your preference is to load a library and share
// it among multiple users or if you only need access to constants
static_libs: ["my-module-name-java"],
...
}
# or
rust_... {
name: ...,
rustlibs: ["my-module-name-rust"],
...
}
ตัวอย่างใน C++
#include "some/package/IFoo.h"
#include "some/package/Thing.h"
...
// use just like traditional AIDL
ตัวอย่างใน Java
import some.package.IFoo;
import some.package.Thing;
...
// use just like traditional AIDL
ตัวอย่างใน Rust
use aidl_interface_name::aidl::some::package::{IFoo, Thing};
...
// use just like traditional AIDL
อินเทอร์เฟซการกำหนดเวอร์ชัน
การประกาศโมดูลที่มีชื่อว่า foo จะเป็นการสร้างเป้าหมายในระบบบิลด์ด้วย
ที่คุณสามารถใช้จัดการ API ของโมดูล เมื่อสร้างเสร็จแล้ว foo-freeze-api
เพิ่มการกำหนด API ใหม่ภายใต้ api_dir
หรือ
aidl_api/name
ทั้งนี้ขึ้นอยู่กับเวอร์ชัน Android และ
เพิ่มไฟล์ .hash
ซึ่งทั้ง 2 ไฟล์แสดงเวอร์ชันที่ตรึงไว้ใหม่
ของ Google foo-freeze-api อัปเดตพร็อพเพอร์ตี้ versions_with_info
ด้วย
เพื่อแสดงเวอร์ชันเพิ่มเติมและ imports
สำหรับเวอร์ชันดังกล่าว โดยพื้นฐานแล้ว
imports
ใน versions_with_info
คัดลอกมาจากช่อง imports
แต่
มีการระบุเวอร์ชันที่เสถียรล่าสุดเป็น imports
ใน versions_with_info
สำหรับ
ซึ่งไม่มีเวอร์ชันที่ชัดเจน
หลังจากระบุพร็อพเพอร์ตี้ versions_with_info
แล้ว ระบบบิลด์จะทำงาน
การตรวจสอบความเข้ากันได้ระหว่างเวอร์ชันที่ตรึงไว้และระหว่าง Top of Tree (ToT)
และเวอร์ชันที่ตรึงไว้ล่าสุด
นอกจากนี้ คุณจำเป็นต้องจัดการการกำหนด API ของเวอร์ชัน ToT เมื่อใดก็ตามที่ API
อัปเดตแล้ว ให้เรียกใช้ foo-update-api เพื่ออัปเดต
aidl_api/name/current
ซึ่งมีคำจำกัดความ API ของเวอร์ชัน ToT
เจ้าของสามารถเพิ่มรายการต่อไปนี้ได้เพื่อรักษาความเสถียรของอินเทอร์เฟซ
- เมธอดต่อท้ายอินเทอร์เฟซ (หรือเมธอดที่มีการกำหนดไว้อย่างชัดแจ้งใหม่ ซีเรียล)
- องค์ประกอบที่อยู่ท้ายไฟล์พาร์เซล (ต้องมีค่าเริ่มต้นเพื่อเพิ่มสําหรับแต่ละรายการ องค์ประกอบ)
- ค่าคงที่
- ใน Android 11 ตัวระบุ
- ใน Android 12 ช่องที่อยู่ท้ายสุดของสหภาพ
ไม่อนุญาตให้ดำเนินการอื่นๆ และไม่มีใครสามารถแก้ไขอินเทอร์เฟซได้ (มิฉะนั้นอาจเสี่ยงต่อการขัดแย้งกับการเปลี่ยนแปลงที่เจ้าของทำไว้)
ในการทดสอบว่าอินเทอร์เฟซทั้งหมดหยุดนิ่งสำหรับการเปิดตัว คุณสามารถสร้างด้วย ชุดตัวแปรสภาพแวดล้อมต่อไปนี้
AIDL_FROZEN_REL=true m ...
- บิลด์ต้องใช้อินเทอร์เฟซ AIDL ที่เสถียรทั้งหมดเพื่อ จะถูกตรึงซึ่งไม่ได้ระบุช่องowner:
AIDL_FROZEN_OWNERS="aosp test"
- บิลด์ต้องใช้อินเทอร์เฟซ AIDL ที่เสถียรทั้งหมด ที่จะตรึงโดยมีช่องowner:
ที่ระบุเป็น "aosp" หรือ "test"
ความเสถียรของการนำเข้า
การอัปเดตเวอร์ชันของการนำเข้าสำหรับเวอร์ชันที่ตรึงไว้ของอินเทอร์เฟซปัจจุบัน ที่เข้ากันได้แบบย้อนหลังที่เลเยอร์ AIDL เวอร์ชันเสถียร แต่การอัปเดตข้อมูลเหล่านี้จำเป็นต้องใช้ อัปเดตเซิร์ฟเวอร์และไคลเอ็นต์ทั้งหมดที่ใช้อินเทอร์เฟซเวอร์ชันก่อนหน้า และบางแอปอาจสับสนเมื่อผสมเวอร์ชันต่างๆ โดยทั่วไปแล้ว สำหรับแพ็กเกจประเภททั่วไปหรือแพ็กเกจทั่วไป วิธีการนี้ปลอดภัยเนื่องจากโค้ดต้อง ถูกเขียนเพื่อจัดการกับประเภทที่ไม่รู้จักจากธุรกรรม IPC อยู่แล้ว
รหัสแพลตฟอร์ม Android android.hardware.graphics.common
คือรหัสที่ใหญ่ที่สุด
ของการอัปเกรดเวอร์ชันประเภทนี้
ใช้อินเทอร์เฟซที่มีเวอร์ชัน
วิธีการเชื่อมต่อ
ขณะรันไทม์ เมื่อพยายามเรียกใช้เมธอดใหม่ในเซิร์ฟเวอร์เก่า ไคลเอ็นต์ใหม่จะได้รับ ข้อผิดพลาดหรือข้อยกเว้นอย่างใดอย่างหนึ่ง ขึ้นอยู่กับแบ็กเอนด์
- แบ็กเอนด์
cpp
ได้รับ::android::UNKNOWN_TRANSACTION
- แบ็กเอนด์
ndk
ได้รับSTATUS_UNKNOWN_TRANSACTION
- แบ็กเอนด์
java
ได้รับandroid.os.RemoteException
พร้อมข้อความว่า ไม่มีการใช้งาน API
สำหรับกลยุทธ์ในการจัดการเรื่องนี้ โปรดดู เวอร์ชันที่กำลังสืบค้นและ โดยใช้ค่าเริ่มต้น
พาร์เซล
เมื่อมีการเพิ่มช่องใหม่ลงในพาร์เซล ไคลเอ็นต์และเซิร์ฟเวอร์เก่าจะทิ้งช่องนั้นไป เมื่อลูกค้าและเซิร์ฟเวอร์ใหม่ได้รับไฟล์แนบเก่า ค่าเริ่มต้นสำหรับพาร์เซลใหม่ โดยอัตโนมัติ ซึ่งหมายความว่าค่าเริ่มต้นต้องเป็น ที่ระบุสำหรับช่องใหม่ทั้งหมดในพื้นที่เก็บข้อมูล
ลูกค้าไม่ควรคาดหวังให้เซิร์ฟเวอร์ใช้ช่องใหม่ เว้นแต่จะทราบ เซิร์ฟเวอร์กำลังใช้งานเวอร์ชันที่มีการกำหนดฟิลด์ (โปรดดู เวอร์ชันการค้นหา)
ค่าแจกแจงและค่าคงที่
ในทำนองเดียวกัน ไคลเอ็นต์และเซิร์ฟเวอร์ควรปฏิเสธหรือละเว้น ค่าคงที่และตัวแจกแจงตามความเหมาะสม เนื่องจากอาจมีการเพิ่ม ในอนาคต ตัวอย่างเช่น เซิร์ฟเวอร์ไม่ควรล้มเลิกเมื่อได้รับ โปรแกรมแจงนับที่ โปรแกรมไม่รู้จัก เซิร์ฟเวอร์จะไม่สนใจ โปรแกรมแจกแจง หรือส่งกลับข้อความบางอย่างเพื่อให้ลูกค้ารู้ว่ารายการไม่ได้รับการสนับสนุนใน นี้
สหภาพ
การพยายามส่งการรวมที่มีฟิลด์ใหม่ล้มเหลว หากผู้รับเป็นตัวเก่าและ
ไม่รู้จักช่องนี้ การนำไปใช้จะไม่เห็นการรวมกับ
ฟิลด์ใหม่ ระบบจะไม่สนใจความล้มเหลวหากเป็น
ธุรกรรมทางเดียว ไม่เช่นนั้น ข้อผิดพลาดจะเป็น BAD_VALUE
(สำหรับ C++ หรือ NDK
แบ็กเอนด์) หรือ IllegalArgumentException
(สำหรับแบ็กเอนด์ Java) ข้อผิดพลาดคือ
ได้รับหากไคลเอ็นต์ส่งชุดยูเนียนไปยังฟิลด์ใหม่ไปยังฟิลด์เก่า
หรือเมื่อไคลเอ็นต์เก่าที่ได้รับสหภาพจากเซิร์ฟเวอร์ใหม่
จัดการเวอร์ชันต่างๆ
เนมสเปซ Linker ใน Android มี aidl
ที่เฉพาะเจาะจงได้เพียง 1 เวอร์ชัน
เพื่อหลีกเลี่ยงสถานการณ์ที่ aidl
ประเภทที่สร้างขึ้นมีหลายแบบ
คำจำกัดความ C++ มีกฎคำจำกัดความเดียวที่ต้องใช้เพียง 1 คำจำกัดความ
ของแต่ละสัญลักษณ์
บิลด์ของ Android แสดงข้อผิดพลาดเมื่อโมดูลอิงตามโมเดลอื่น
ของไลบรารี aidl_interface
เดียวกัน โมดูลอาจขึ้นอยู่กับ
ไลบรารีเหล่านี้โดยตรงหรือโดยอ้อมผ่านทรัพยากร Dependency ของไลบรารี
ทรัพยากร Dependency ข้อผิดพลาดเหล่านี้แสดงกราฟทรัพยากร Dependency จากโมดูลที่ล้มเหลวไปยัง
เวอร์ชันที่ขัดแย้งกันของไลบรารี aidl_interface
ทั้งหมด
จำเป็นต้องอัปเดตทรัพยากร Dependency ให้มีทรัพยากรเดียวกัน (โดยปกติจะเป็นเวอร์ชันล่าสุด) เดียวกัน
ของไลบรารีเหล่านี้
หากโมดูลต่างๆ จำนวนมากใช้ไลบรารีอินเทอร์เฟซ ก็อาจเป็นประโยชน์
เพื่อสร้าง cc_defaults
, java_defaults
และ rust_defaults
สำหรับกลุ่ม
และกระบวนการที่ต้องใช้เวอร์ชันเดียวกัน เมื่อแนะนำ
อินเทอร์เฟซเวอร์ชันใหม่ สามารถอัปเดตค่าเริ่มต้นได้ และโมดูลทั้งหมด
ที่กำลังใช้เวอร์ชันทั้งหมดจะได้รับการอัปเดตร่วมกัน เพื่อให้มั่นใจว่าไม่ได้ใช้เวอร์ชันอื่น
ของอินเทอร์เฟซ
cc_defaults {
name: "my.aidl.my-process-group-ndk-shared",
shared_libs: ["my.aidl-V3-ndk"],
...
}
cc_library {
name: "foo",
defaults: ["my.aidl.my-process-group-ndk-shared"],
...
}
cc_binary {
name: "bar",
defaults: ["my.aidl.my-process-group-ndk-shared"],
...
}
เมื่อ aidl_interface
โมดูลนำเข้าโมดูลอื่นๆ aidl_interface
โมดูลนี้สร้างขึ้น
ทรัพยากร Dependency เพิ่มเติมที่ต้องใช้เวอร์ชันที่เฉพาะเจาะจงร่วมกัน ช่วงเวลานี้
อาจจัดการได้ยากเมื่อมี aidl_interface
ทั่วๆ ไป
โมดูลที่นำเข้าในหลายๆ โมดูล aidl_interface
ที่ใช้
โดยใช้กระบวนการเดียวกัน
aidl_interfaces_defaults
สามารถใช้เพื่อเก็บรักษาคำจำกัดความของ
ทรัพยากร Dependency เวอร์ชันล่าสุดสำหรับ aidl_interface
ที่อัปเดตได้ใน
ที่เดียว และใช้โดยโมดูล aidl_interface
ทั้งหมดที่ต้องการนำเข้า
อินเทอร์เฟซทั่วไป
aidl_interface_defaults {
name: "android.popular.common-latest-defaults",
imports: ["android.popular.common-V3"],
...
}
aidl_interface {
name: "android.foo",
defaults: ["my.aidl.latest-ndk-shared"],
...
}
aidl_interface {
name: "android.bar",
defaults: ["my.aidl.latest-ndk-shared"],
...
}
การพัฒนาที่อิงตาม Flag
อินเทอร์เฟซที่อยู่ระหว่างการพัฒนา (ยกเลิกการตรึง) จะใช้ในอุปกรณ์ที่เผยแพร่ไม่ได้เนื่องจาก แต่ไม่รับประกันว่าจะเข้ากันได้แบบย้อนหลัง
AIDL รองรับรันไทม์สำรองสำหรับไลบรารีอินเทอร์เฟซที่ไม่ได้ตรึงเหล่านี้ตามลำดับ เพื่อเขียนโค้ดด้วยเวอร์ชันที่ไม่ได้ตรึงไว้ล่าสุดและยังคงใช้งาน ในอุปกรณ์ที่เผยแพร่ ลักษณะการทำงานที่เข้ากันได้กับไคลเอ็นต์แบบย้อนหลังนั้นคล้ายกับ การทำงานที่มีอยู่และการทำงานสำรอง การติดตั้งใช้งานก็จะต้องเป็นไปตาม พฤติกรรมเหล่านั้น โปรดดู ใช้อินเทอร์เฟซที่มีเวอร์ชัน
Flag บิลด์ AIDL
แฟล็กที่ควบคุมลักษณะการทำงานนี้คือ RELEASE_AIDL_USE_UNFROZEN
กำหนดไว้ใน build/release/build_flags.bzl
true
หมายถึงเวอร์ชันที่ไม่ได้ตรึงไว้ของ
อินเทอร์เฟซจะใช้ในเวลาที่เรียกใช้ และ false
หมายถึงไลบรารีของ
เวอร์ชันที่ยกเลิกการตรึงแล้วทั้งหมดจะทำงานเหมือนกับเวอร์ชันที่ตรึงไว้ล่าสุด
คุณสามารถลบล้างการตั้งค่าสถานะเป็น true
สำหรับ
ในพื้นที่ แต่ต้องเปลี่ยนกลับไปเป็น false
ก่อนที่จะเปิดตัว ราคาปกติ
พัฒนาได้ด้วยการกำหนดค่าที่ตั้งค่าแฟล็กเป็น true
เมทริกซ์ความเข้ากันได้และไฟล์ Manifest
ออบเจ็กต์อินเทอร์เฟซผู้ให้บริการ (ออบเจ็กต์ VINTF) กำหนด เวอร์ชันที่คาดไว้ และเวอร์ชันที่แสดงในแต่ละด้านของ ในอินเทอร์เฟซของผู้ให้บริการ
อุปกรณ์ที่ไม่ใช่หมึกกระดองส่วนใหญ่จะกำหนดเป้าหมายเมทริกซ์ความเข้ากันได้ล่าสุด
หลังจากที่อินเทอร์เฟซหยุดทำงานเท่านั้น ดังนั้น AIDL จึงไม่มีความแตกต่าง
ไลบรารีอิงตาม RELEASE_AIDL_USE_UNFROZEN
เมทริกซ์
เพิ่มอินเทอร์เฟซที่พาร์ทเนอร์เป็นเจ้าของลงในเฉพาะอุปกรณ์หรือผลิตภัณฑ์เฉพาะ
เมทริกซ์ความเข้ากันได้ที่อุปกรณ์กำหนดเป้าหมายระหว่างการพัฒนา ดังนั้นเมื่อ
มีการเพิ่มอินเทอร์เฟซเวอร์ชันใหม่ที่ไม่ได้ตรึงไว้
ลงในเมทริกซ์ความเข้ากันได้
เวอร์ชันที่ตรึงไว้ก่อนหน้านี้จะยังคง
RELEASE_AIDL_USE_UNFROZEN=false
คุณสามารถจัดการการดำเนินการนี้ได้โดยใช้
ไฟล์เมทริกซ์ความเข้ากันได้สำหรับ RELEASE_AIDL_USE_UNFROZEN
ต่างๆ
หรืออนุญาตทั้งสองเวอร์ชันในไฟล์เมทริกซ์ความเข้ากันได้ไฟล์เดียว
ซึ่งใช้ในการกำหนดค่าทั้งหมด
เช่น เมื่อเพิ่มเวอร์ชัน 4 ที่ไม่ได้ตรึงไว้ ให้ใช้ <version>3-4</version>
เมื่อเวอร์ชัน 4 หยุดทำงาน คุณจะนำเวอร์ชัน 3 ออกจากเมทริกซ์ความเข้ากันได้ได้
เนื่องจากมีการใช้เวอร์ชัน 4 ที่ตรึงเมื่อ RELEASE_AIDL_USE_UNFROZEN
คือ
false
Manifest
ใน Android 15 มีการเปลี่ยนแปลงใน libvintf
เป็น
แก้ไขไฟล์ Manifest ในเวลาสร้างตามค่าของ
RELEASE_AIDL_USE_UNFROZEN
ไฟล์ Manifest และส่วนไฟล์ Manifest จะประกาศว่าอินเทอร์เฟซเวอร์ชันใด
เกิดขึ้นจริง เมื่อใช้อินเทอร์เฟซเวอร์ชันล่าสุดที่ไม่ได้ตรึงไว้
ไฟล์ Manifest จะต้องได้รับการอัปเดตให้สอดคล้องกับเวอร์ชันใหม่นี้ วันและเวลา
RELEASE_AIDL_USE_UNFROZEN=false
รายการไฟล์ Manifest จะปรับตาม
libvintf
เพื่อแสดงการเปลี่ยนแปลงในไลบรารี AIDL ที่สร้างขึ้น เวอร์ชัน
ถูกแก้ไขจากเวอร์ชันที่ไม่ได้ตรึงไว้ N
เป็น
เวอร์ชันที่ตรึงไว้ล่าสุด N - 1
ผู้ใช้จึงไม่ต้องจัดการ
หรือไฟล์ Manifest สำหรับบริการต่างๆ แต่ละรายการ
การเปลี่ยนแปลงไคลเอ็นต์ HAL
รหัสไคลเอ็นต์ HAL ต้องเข้ากันได้แบบย้อนหลังกับเวอร์ชันที่ตรึงไว้ก่อนหน้าที่รองรับ
เวอร์ชัน เมื่อ RELEASE_AIDL_USE_UNFROZEN
คือfalse
บริการจะดูอยู่ตลอดเวลา
เช่น เวอร์ชันที่ตรึงไว้ล่าสุดหรือก่อนหน้านี้ (ตัวอย่างเช่น การเรียกใช้
"ใหม่ที่ไม่ได้ตรึง"
แสดงผล UNKNOWN_TRANSACTION
หรือฟิลด์ parcelable
ใหม่มีฟิลด์
ค่าเริ่มต้น) ไคลเอ็นต์เฟรมเวิร์ก Android ต้องเป็นไคลเอ็นต์แบบย้อนหลัง
สามารถใช้ร่วมกับเวอร์ชันก่อนหน้าอื่นๆ ได้ด้วย แต่นี่เป็นรายละเอียดใหม่สำหรับ
ไคลเอ็นต์ของผู้ให้บริการและไคลเอ็นต์ของอินเทอร์เฟซที่พาร์ทเนอร์เป็นเจ้าของ
การเปลี่ยนแปลงการใช้ HAL
ความแตกต่างที่เห็นได้ชัดที่สุดของการพัฒนา HAL กับการพัฒนาที่อิงตาม Flag คือ
ข้อกำหนดในการใช้งาน HAL ให้สามารถเข้ากันได้แบบย้อนหลังกับ
เวอร์ชันที่ตรึงไว้ให้ทำงานเมื่อ RELEASE_AIDL_USE_UNFROZEN
คือ false
การพิจารณาความเข้ากันได้แบบย้อนหลังในการใช้งานและโค้ดของอุปกรณ์เป็น
สำหรับการออกกำลังกาย ดูใช้เวอร์ชันที่มีเวอร์ชัน
อินเทอร์เฟซ
ข้อควรพิจารณาเกี่ยวกับความเข้ากันได้แบบย้อนหลังจะเหมือนกันสำหรับ ไคลเอ็นต์และเซิร์ฟเวอร์ และสำหรับโค้ดเฟรมเวิร์กและโค้ดผู้ให้บริการ แต่มี ความแตกต่างเล็กน้อยที่คุณต้องระวัง เนื่องจากตอนนี้คุณสามารถ ใช้ 2 เวอร์ชันที่ใช้ซอร์สโค้ดเดียวกัน (เวอร์ชันปัจจุบันที่ไม่ได้ตรึงไว้ เวอร์ชัน)
ตัวอย่าง: อินเทอร์เฟซมีเวอร์ชันที่ตรึงไว้ 3 เวอร์ชัน อินเทอร์เฟซจะได้รับการอัปเดตด้วย
เมธอดใหม่ ทั้งไคลเอ็นต์และบริการได้รับการอัปเดตเพื่อใช้เวอร์ชันใหม่ 4
ไลบรารี เนื่องจากไลบรารี V4 อิงตามเวอร์ชันที่ไม่ได้ตรึงไว้
ก็ทำงานเหมือนเวอร์ชันที่ตรึงไว้ล่าสุด เวอร์ชัน 3 เมื่อ
RELEASE_AIDL_USE_UNFROZEN
มีค่าเป็น false
และป้องกันไม่ให้ใช้เมธอดใหม่
เมื่ออินเทอร์เฟซค้าง ค่าทั้งหมดของ RELEASE_AIDL_USE_UNFROZEN
จะใช้
เวอร์ชันที่ถูกตรึงไว้ และโค้ดที่จัดการความเข้ากันได้แบบย้อนหลังสามารถนำออกได้
เมื่อเรียกเมธอดใน Callback คุณต้องจัดการกับกรณีอย่างสุภาพเมื่อ
ส่งคืน UNKNOWN_TRANSACTION
แล้ว ลูกค้าอาจใช้งาน
เวอร์ชัน Callback ตามการกำหนดค่ารุ่น คุณจึงไม่สามารถ
สมมติว่าไคลเอ็นต์ส่งเวอร์ชันใหม่ล่าสุด และวิธีใหม่อาจส่งคืนมา
นี้ ซึ่งคล้ายกับความเสถียรของไคลเอ็นต์ AIDL ที่ใช้แบบเดิม
ความสามารถในการใช้งานร่วมกันกับเซิร์ฟเวอร์จะอธิบายไว้ในหัวข้อใช้เวอร์ชัน
อินเทอร์เฟซ
// Get the callback along with the version of the callback
ScopedAStatus RegisterMyCallback(const std::shared_ptr<IMyCallback>& cb) override {
mMyCallback = cb;
// Get the version of the callback for later when we call methods on it
auto status = mMyCallback->getInterfaceVersion(&mMyCallbackVersion);
return status;
}
// Example of using the callback later
void NotifyCallbackLater() {
// From the latest frozen version (V2)
mMyCallback->foo();
// Call this method from the unfrozen V3 only if the callback is at least V3
if (mMyCallbackVersion >= 3) {
mMyCallback->bar();
}
}
ช่องใหม่ในประเภทที่มีอยู่ (parcelable
, enum
, union
) อาจ
ไม่มีอยู่หรือมีค่าเริ่มต้นเมื่อ RELEASE_AIDL_USE_UNFROZEN
คือ
false
และค่าของช่องใหม่ที่บริการพยายามส่งจะถูกตัดออก
ออกจากกระบวนการ
ส่งประเภทใหม่ที่เพิ่มเข้ามาในเวอร์ชันที่ไม่ได้ตรึงแล้วนี้ไม่ได้ หรือได้รับผ่านอินเทอร์เฟซ
การติดตั้งใช้งานไม่เคยได้รับการเรียกร้องวิธีการใหม่ๆ จากลูกค้าเมื่อ
RELEASE_AIDL_USE_UNFROZEN
คือfalse
โปรดใช้โปรแกรมแจกแจงใหม่กับเวอร์ชันที่เริ่มใช้เท่านั้น ไม่ใช่เวอร์ชันก่อนหน้า
โดยปกติคุณจะใช้ foo->getInterfaceVersion()
เพื่อดูเวอร์ชันรีโมต
ของอินเทอร์เฟซอยู่ อย่างไรก็ตาม การสนับสนุนการกำหนดเวอร์ชันตาม Flag คุณจะ
ที่ใช้งาน 2 เวอร์ชันแตกต่างกัน คุณจึงอาจต้องการหาเวอร์ชันของ
อินเทอร์เฟซปัจจุบัน ซึ่งทำได้โดยขอรับเวอร์ชันอินเทอร์เฟซของ
ออบเจ็กต์ปัจจุบัน เช่น this->getInterfaceVersion()
หรือออบเจ็กต์อื่นๆ
สำหรับ my_ver
ดูการค้นหาเวอร์ชันอินเทอร์เฟซของรีโมต
ออบเจ็กต์
เพื่อดูข้อมูลเพิ่มเติม
อินเทอร์เฟซ VINTF เวอร์ชันเสถียรใหม่
เมื่อมีการเพิ่มแพ็กเกจอินเทอร์เฟซ AIDL ใหม่ จะไม่มีเวอร์ชันที่ตรึงไว้ล่าสุด
ไม่มีลักษณะการทำงานที่จะย้อนกลับไปเมื่อ RELEASE_AIDL_USE_UNFROZEN
มีค่า
false
อย่าใช้อินเทอร์เฟซเหล่านี้ เมื่อRELEASE_AIDL_USE_UNFROZEN
คือ
false
ผู้จัดการบริการไม่อนุญาตให้บริการลงทะเบียนอินเทอร์เฟซ
ลูกค้าจะหาไม่เจอ
คุณสามารถเพิ่มบริการแบบมีเงื่อนไขตามค่าของ
Flag RELEASE_AIDL_USE_UNFROZEN
ในไฟล์ยี่ห้ออุปกรณ์:
ifeq ($(RELEASE_AIDL_USE_UNFROZEN),true)
PRODUCT_PACKAGES += \
android.hardware.health.storage-service
endif
หากบริการเป็นส่วนหนึ่งของกระบวนการที่ใหญ่กว่า คุณจึงเพิ่มบริการลงในอุปกรณ์ไม่ได้
อย่างมีเงื่อนไข คุณจะสามารถตรวจสอบว่ามีการประกาศบริการ
IServiceManager::isDeclared()
หากมีการประกาศแล้วแต่ลงทะเบียนไม่สำเร็จ
ล้มเลิกกระบวนการ หากไม่ได้ประกาศไว้ การลงทะเบียนอาจล้มเหลว
หมึกกระดองเป็นเครื่องมือพัฒนา
ทุกปีหลังจากที่ VINTF หยุดทํางาน เราจะปรับความเข้ากันได้ของเฟรมเวิร์ก
เมทริกซ์ (FCM) target-level
และ PRODUCT_SHIPPING_API_LEVEL
ของหมึกกระดอง
เพื่อให้แสดงอุปกรณ์ที่จะเปิดตัวในปีหน้า เราปรับ
target-level
และ PRODUCT_SHIPPING_API_LEVEL
เพื่อให้แน่ใจว่ามี
การเปิดตัวอุปกรณ์ที่ได้รับการทดสอบและเป็นไปตามข้อกำหนดใหม่ของปีหน้า
เมื่อRELEASE_AIDL_USE_UNFROZEN
อายุ true
ปี หมึกกระดองจะ
ซึ่งใช้สำหรับการพัฒนา Android รุ่นต่อๆ ไป กำหนดเป้าหมายเป็น Android ในปีหน้า
ระดับ FCM และ PRODUCT_SHIPPING_API_LEVEL
ของรุ่น ซึ่งกำหนดให้เป็นไปตามข้อกำหนด
ข้อกำหนดของซอฟต์แวร์ของผู้ให้บริการ (VSR) สำหรับรุ่นถัดไป
เมื่อ RELEASE_AIDL_USE_UNFROZEN
อายุ false
ปี หมึกกระดองมีรายการก่อนหน้า
target-level
และ PRODUCT_SHIPPING_API_LEVEL
เพื่อแสดงอุปกรณ์ที่เผยแพร่
ใน Android 14 และต่ำกว่า ความแตกต่างนี้คือ
ประสบความสำเร็จด้วยสาขา Git ต่างๆ ที่ไม่รับการเปลี่ยนแปลงใน FCM
target-level
, ระดับ API การจัดส่ง หรือโค้ดอื่นๆ ที่กำหนดเป้าหมายไปยัง
กฎการตั้งชื่อโมดูล
ใน Android 11 สําหรับชุดค่าผสมแต่ละเวอร์ชันและ
เปิดใช้แบ็กเอนด์ ระบบจะสร้างโมดูลไลบรารีสตับขึ้นโดยอัตโนมัติ วิธีบอกต่อ
ไปยังโมดูลไลบรารีต้นขั้วที่ต้องการสำหรับการลิงก์ อย่าใช้ชื่อของ
aidl_interface
แต่ชื่อของโมดูลคลังสตับ
ifacename-version-backend โดยที่
ifacename
: ชื่อของโมดูลaidl_interface
version
เป็นอย่างใดอย่างหนึ่งVversion-number
สำหรับเวอร์ชันที่ตรึงไว้Vlatest-frozen-version-number + 1
สำหรับ เวอร์ชันปลายต้น (ยังไม่ถูกแช่แข็ง)
backend
เป็นอย่างใดอย่างหนึ่งjava
สำหรับแบ็กเอนด์ Javacpp
สำหรับแบ็กเอนด์ C++ndk
หรือndk_platform
สำหรับแบ็กเอนด์ NDK ตัวเลือกแรกมีไว้สำหรับแอป และ กรณีหลังมีไว้สำหรับการใช้งานแพลตฟอร์มจนถึง Android 13 ใน Android 13 ขึ้นไป โปรดใช้ndk
เท่านั้นrust
สำหรับแบ็กเอนด์ของ Rust
สมมติว่ามีโมดูลชื่อ foo และเวอร์ชันล่าสุดคือ 2 และรองรับทั้ง NDK และ C++ ในกรณีนี้ AIDL จะสร้างโมดูลต่อไปนี้
- อิงจากเวอร์ชัน 1
foo-V1-(java|cpp|ndk|ndk_platform|rust)
- อิงตามเวอร์ชัน 2 (เวอร์ชันที่เสถียรล่าสุด)
foo-V2-(java|cpp|ndk|ndk_platform|rust)
- ตามเวอร์ชันข้อกำหนดในการให้บริการ
foo-V3-(java|cpp|ndk|ndk_platform|rust)
เทียบกับ Android 11
foo-backend
ซึ่งแสดงเวอร์ชันเสถียรล่าสุด เวอร์ชันเปลี่ยนเป็นfoo-V2-backend
foo-unstable-backend
ซึ่งระบุถึงข้อกำหนดในการให้บริการ เวอร์ชันเปลี่ยนเป็นfoo-V3-backend
ชื่อไฟล์เอาต์พุตจะเหมือนกับชื่อโมดูลเสมอ
- จากเวอร์ชัน 1:
foo-V1-(cpp|ndk|ndk_platform|rust).so
- จากเวอร์ชัน 2:
foo-V2-(cpp|ndk|ndk_platform|rust).so
- ตามเวอร์ชันข้อกำหนดในการให้บริการ:
foo-V3-(cpp|ndk|ndk_platform|rust).so
โปรดทราบว่าคอมไพเลอร์ AIDL จะไม่สร้างโมดูลเวอร์ชัน unstable
หรือโมดูลที่ไม่มีเวอร์ชันสำหรับอินเทอร์เฟซ AIDL ที่เสถียร
ใน Android 12 ชื่อโมดูลที่สร้างจาก
อินเทอร์เฟซ AIDL เวอร์ชันเสถียรจะมีเวอร์ชันของตัวเองเสมอ
วิธีการใหม่สำหรับอินเทอร์เฟซเมตา
Android 10 เพิ่มวิธีการอินเทอร์เฟซเมตาหลายวิธีสำหรับ AIDL ที่เสถียร
ค้นหาเวอร์ชันอินเทอร์เฟซของออบเจ็กต์ระยะไกล
ไคลเอ็นต์ค้นหาเวอร์ชันและแฮชของอินเทอร์เฟซที่ออบเจ็กต์ระยะไกลได้ กำลังใช้และเปรียบเทียบค่าที่แสดงผลกับค่าของอินเทอร์เฟซ ที่ลูกค้าใช้อยู่
ตัวอย่างที่มีแบ็กเอนด์ cpp
sp<IFoo> foo = ... // the remote object
int32_t my_ver = IFoo::VERSION;
int32_t remote_ver = foo->getInterfaceVersion();
if (remote_ver < my_ver) {
// the remote side is using an older interface
}
std::string my_hash = IFoo::HASH;
std::string remote_hash = foo->getInterfaceHash();
ตัวอย่างที่มีแบ็กเอนด์ ndk
(และ ndk_platform
)
IFoo* foo = ... // the remote object
int32_t my_ver = IFoo::version;
int32_t remote_ver = 0;
if (foo->getInterfaceVersion(&remote_ver).isOk() && remote_ver < my_ver) {
// the remote side is using an older interface
}
std::string my_hash = IFoo::hash;
std::string remote_hash;
foo->getInterfaceHash(&remote_hash);
ตัวอย่างที่มีแบ็กเอนด์ java
IFoo foo = ... // the remote object
int myVer = IFoo.VERSION;
int remoteVer = foo.getInterfaceVersion();
if (remoteVer < myVer) {
// the remote side is using an older interface
}
String myHash = IFoo.HASH;
String remoteHash = foo.getInterfaceHash();
สำหรับภาษา Java ฝั่งระยะไกลต้องใช้ getInterfaceVersion()
และ
getInterfaceHash()
ดังนี้ (ใช้ super
แทน IFoo
เพื่อหลีกเลี่ยง
ในการคัดลอกและวางที่ผิดพลาด คำอธิบายประกอบ @SuppressWarnings("static")
อาจ
เพื่อปิดใช้คำเตือน ทั้งนี้ขึ้นอยู่กับการกำหนดค่า javac
) ดังนี้
class MyFoo extends IFoo.Stub {
@Override
public final int getInterfaceVersion() { return super.VERSION; }
@Override
public final String getInterfaceHash() { return super.HASH; }
}
เนื่องจากมีการแชร์ชั้นเรียนที่สร้างขึ้น (IFoo
, IFoo.Stub
ฯลฯ)
ระหว่างไคลเอ็นต์และเซิร์ฟเวอร์ (เช่น คลาสอาจอยู่ในระบบ
classpath) เมื่อมีการแชร์ชั้นเรียน เซิร์ฟเวอร์ก็จะลิงก์กับ
ชั้นเรียนเวอร์ชันใหม่ล่าสุด แม้ว่าอาจจะสร้างขึ้นโดยเวอร์ชันเก่า
ของอินเทอร์เฟซ หากใช้อินเทอร์เฟซ Meta นี้ใน
จะมีการแสดงเวอร์ชันล่าสุดเสมอ อย่างไรก็ตาม การใช้เมธอด
ดังที่กล่าวข้างต้น หมายเลขเวอร์ชันของอินเทอร์เฟซจะฝังอยู่ในโค้ดของเซิร์ฟเวอร์
(เนื่องจาก IFoo.VERSION
เป็น static final int
ที่มีการในบรรทัดเมื่อมีการอ้างอิง)
ดังนั้น เมธอดดังกล่าวจะแสดงเวอร์ชันที่เซิร์ฟเวอร์ใช้อยู่จริงๆ ได้
จัดการกับอินเทอร์เฟซรุ่นเก่า
ไคลเอ็นต์อาจได้รับการอัปเดตด้วย AIDL เวอร์ชันใหม่
แต่เซิร์ฟเวอร์ใช้อินเทอร์เฟซ AIDL แบบเก่า ในกรณีดังกล่าว
การเรียกเมธอดในอินเทอร์เฟซเก่าแสดงผล UNKNOWN_TRANSACTION
เมื่อใช้ AIDL เวอร์ชันเสถียร ไคลเอ็นต์จะควบคุมสิ่งต่างๆ ได้มากขึ้น ในฝั่งไคลเอ็นต์ คุณสามารถกำหนด การใช้งานเริ่มต้นสำหรับอินเทอร์เฟซ AIDL เมธอดในค่าเริ่มต้น จะเรียกใช้การติดตั้งใช้งานก็ต่อเมื่อไม่มีการใช้วิธีการดังกล่าวจากระยะไกล (เนื่องจากสร้างด้วยอินเทอร์เฟซเวอร์ชันเก่า) ตั้งแต่ปี ค่าเริ่มต้นได้รับการตั้งค่าเป็นทั่วโลก ไม่ควรใช้ค่าเริ่มต้นจากที่อาจมีการแชร์ บริบทเหล่านี้
ตัวอย่างใน C++ ใน Android 13 ขึ้นไป
class MyDefault : public IFooDefault {
Status anAddedMethod(...) {
// do something default
}
};
// once per an interface in a process
IFoo::setDefaultImpl(::android::sp<MyDefault>::make());
foo->anAddedMethod(...); // MyDefault::anAddedMethod() will be called if the
// remote side is not implementing it
ตัวอย่างใน Java
IFoo.Stub.setDefaultImpl(new IFoo.Default() {
@Override
public xxx anAddedMethod(...) throws RemoteException {
// do something default
}
}); // once per an interface in a process
foo.anAddedMethod(...);
คุณไม่จำเป็นต้องติดตั้งใช้งานเริ่มต้นของเมธอดทั้งหมดใน AIDL
ของ Google วิธีการที่รับประกันว่าจะใช้งานจากระยะไกล
(เพราะมั่นใจว่ารีโมตสร้างขึ้นเมื่อเมธอดอยู่ใน
คำอธิบายอินเทอร์เฟซ AIDL) ไม่จำเป็นต้องลบล้างใน impl
เริ่มต้น
แปลง AIDL ที่มีอยู่เป็น AIDL ที่มีโครงสร้างหรือเสถียร
หากคุณมีอินเทอร์เฟซ AIDL และโค้ดที่ใช้อินเทอร์เฟซดังกล่าวอยู่แล้ว ให้ใช้รายการต่อไปนี้ ขั้นตอนการแปลงอินเทอร์เฟซเป็นอินเทอร์เฟซ AIDL เวอร์ชันเสถียร
ระบุทรัพยากร Dependency ทั้งหมดในอินเทอร์เฟซ สำหรับทุกแพ็กเกจ ขึ้นอยู่กับว่าระบบกำหนดแพ็กเกจไว้ใน AIDL เวอร์ชันเสถียรหรือไม่ ถ้า ไม่ได้กำหนด ต้องแปลงแพ็กเกจ
แปลงพาร์เซลทั้งหมดในอินเทอร์เฟซให้เป็นไฟล์พาร์เซลที่มีความเสถียร ( ไฟล์อินเทอร์เฟซเองก็จะไม่เปลี่ยนแปลง) ดำเนินการโดย เพื่อแสดงโครงสร้างโดยตรงในไฟล์ AIDL ชั้นเรียนการจัดการต้อง เขียนใหม่เพื่อใช้ประเภทใหม่ๆ เหล่านี้ ซึ่งสามารถทำได้ก่อนที่จะสร้าง แพ็กเกจ
aidl_interface
(ด้านล่าง)สร้างแพ็กเกจ
aidl_interface
(ตามที่อธิบายไว้ข้างต้น) ที่มี ชื่อของโมดูล ทรัพยากร Dependency และข้อมูลอื่นๆ ที่คุณต้องการ นอกจากนี้ ยังต้องมีเวอร์ชันเพื่อให้มีความเสถียร (ไม่ใช่แค่มีโครงสร้าง) ด้วย ดูข้อมูลเพิ่มเติมได้ที่การกำหนดเวอร์ชันอินเทอร์เฟซ