AIDL เวอร์ชันเสถียร

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 ที่ระบุ อินเทอร์เฟซ AIDL
  • srcs: รายการไฟล์ต้นทางของ 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 12
  • versions: อินเทอร์เฟซเวอร์ชันก่อนหน้าที่ ค้างที่ api_dir เริ่มต้นใน Android 11 versions มีราคาต่ำกว่า aidl_api/name หากไม่มีเวอร์ชันใดที่หยุดนิ่งของอินเทอร์เฟซ ไม่ควรระบุข้อมูลนี้และจะไม่มีการตรวจสอบความเข้ากันได้ ช่องนี้ได้แทนที่ด้วย versions_with_info สำหรับ Android แล้ว 13 ปีขึ้นไป
  • versions_with_info: รายการทูเปิ้ล แต่ละรายการมีชื่อของ เวอร์ชันที่ตรึงไว้และรายการที่มีการนำเข้าเวอร์ชันของ aidl_interface อื่นๆ โมดูลที่ aidl_interface เวอร์ชันนี้นำเข้ามา คำจำกัดความ ของเวอร์ชัน V ของอินเทอร์เฟซ AIDL อยู่ที่ IFACE aidl_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 14
  • backend.<type>.enabled: แฟล็กเหล่านี้จะสลับแบ็กเอนด์แต่ละรายการที่ คอมไพเลอร์ AIDL จะสร้างโค้ดให้ แบ็กเอนด์ 4 รายการ รองรับ Java, C++, NDK และ Rust เปิดใช้แบ็กเอนด์ Java, C++ และ NDK โดยค่าเริ่มต้น หากไม่จำเป็นต้องใช้แบ็กเอนด์ 3 รายการนี้ ปิดใช้อย่างชัดแจ้ง Rust จะปิดใช้โดยค่าเริ่มต้นจนถึง Android 15 (ทดลอง AOSP)
  • backend.<type>.apex_available: รายการชื่อ APEX ที่สร้างขึ้น มีให้บริการสำหรับ Stub Library
  • backend.[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) ข้อผิดพลาดคือ ได้รับหากไคลเอ็นต์ส่งชุดยูเนียนไปยังฟิลด์ใหม่ไปยังฟิลด์เก่า หรือเมื่อไคลเอ็นต์เก่าที่ได้รับสหภาพจากเซิร์ฟเวอร์ใหม่

การพัฒนาที่อิงตาม 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 (เวอร์ชันทดลอง AOSP) เราจะเปิดตัวการเปลี่ยนแปลงใน 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 สำหรับแบ็กเอนด์ Java
    • cpp สำหรับแบ็กเอนด์ 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 เวอร์ชันเสถียร

  1. ระบุทรัพยากร Dependency ทั้งหมดในอินเทอร์เฟซ สำหรับทุกแพ็กเกจ ขึ้นอยู่กับว่าระบบกำหนดแพ็กเกจไว้ใน AIDL เวอร์ชันเสถียรหรือไม่ ถ้า ไม่ได้กำหนด ต้องแปลงแพ็กเกจ

  2. แปลงพาร์เซลทั้งหมดในอินเทอร์เฟซให้เป็นไฟล์พาร์เซลที่มีความเสถียร ( ไฟล์อินเทอร์เฟซเองก็จะไม่เปลี่ยนแปลง) ดำเนินการโดย เพื่อแสดงโครงสร้างโดยตรงในไฟล์ AIDL ชั้นเรียนการจัดการต้อง เขียนใหม่เพื่อใช้ประเภทใหม่ๆ เหล่านี้ ซึ่งสามารถทำได้ก่อนที่จะสร้าง แพ็กเกจ aidl_interface (ด้านล่าง)

  3. สร้างแพ็กเกจ aidl_interface (ตามที่อธิบายไว้ข้างต้น) ที่มี ชื่อของโมดูล ทรัพยากร Dependency และข้อมูลอื่นๆ ที่คุณต้องการ นอกจากนี้ ยังต้องมีเวอร์ชันเพื่อให้มีความเสถียร (ไม่ใช่แค่มีโครงสร้าง) ด้วย ดูข้อมูลเพิ่มเติมได้ที่การกำหนดเวอร์ชันอินเทอร์เฟซ