การใช้ Java SDK Library

แพลตฟอร์ม Android มีไลบรารี Java ที่ใช้ร่วมกันจำนวนมาก ซึ่งสามารถเลือกรวมไว้ในคลาสพาธของแอปได้ด้วยแท็ก <uses-library> ในรายการแอป แอปเชื่อมโยงกับไลบรารีเหล่านี้ ดังนั้นให้ปฏิบัติต่อไลบรารีเหล่านี้เหมือนกับส่วนที่เหลือของ Android API ในแง่ของความเข้ากันได้ การตรวจสอบ API และการสนับสนุนเครื่องมือ อย่างไรก็ตาม โปรดทราบว่าไลบรารีส่วนใหญ่ไม่มีคุณลักษณะเหล่านี้

ประเภทโมดูล java_sdk_library ช่วยจัดการไลบรารีประเภทนี้ ผู้ผลิตอุปกรณ์สามารถใช้กลไกนี้สำหรับไลบรารี Java ที่ใช้ร่วมกันของตนเอง เพื่อรักษาความเข้ากันได้แบบย้อนหลังสำหรับ API ของตน หากผู้ผลิตอุปกรณ์ใช้ไลบรารี Java ที่ใช้ร่วมกันของตนเองผ่านแท็ก <uses-library> แทนเส้นทางบูตคลาส java_sdk_library จะสามารถตรวจสอบได้ว่าไลบรารี Java เหล่านั้นมีความเสถียรของ API หรือไม่

java_sdk_library ใช้ SDK API เสริมสำหรับใช้งานโดยแอป ไลบรารีที่ใช้งานผ่าน java_sdk_library ในไฟล์บิลด์ของคุณ ( Android.bp ) ดำเนินการต่อไปนี้:

  • ไลบรารี stubs ถูกสร้างขึ้นเพื่อรวม stubs , stubs.system และ stubs.test ไลบรารี stubs เหล่านี้ถูกสร้างขึ้นโดยการจดจำคำอธิบายประกอบ @hide , @SystemApi และ @TestApi
  • java_sdk_library จัดการไฟล์ข้อกำหนด API (เช่น current.txt ) ในไดเรกทอรีย่อย API ไฟล์เหล่านี้ได้รับการตรวจสอบกับโค้ดล่าสุดเพื่อให้แน่ใจว่าเป็นเวอร์ชันล่าสุด หากไม่เป็นเช่นนั้น คุณจะได้รับข้อความแสดงข้อผิดพลาดที่อธิบายวิธีการอัปเดต ตรวจสอบการเปลี่ยนแปลงการอัปเดตทั้งหมดด้วยตนเองเพื่อให้แน่ใจว่าตรงกับความคาดหวังของคุณ

    หากต้องการอัปเดต API ทั้งหมด ให้ใช้ m update-api หากต้องการตรวจสอบว่า API เป็นเวอร์ชันล่าสุด ให้ใช้ m checkapi
  • ไฟล์ข้อกำหนด API จะได้รับการตรวจสอบกับ Android เวอร์ชันที่เผยแพร่ล่าสุดเพื่อให้แน่ใจว่า API สามารถใช้งานร่วมกับเวอร์ชันก่อนหน้าได้ โมดูล java_sdk_library ที่จัดเตรียมไว้เป็นส่วนหนึ่งของ AOSP จะวางเวอร์ชันที่เผยแพร่ก่อนหน้านี้ไว้ใน prebuilts/sdk/<latest number>
  • สำหรับการตรวจสอบไฟล์ข้อกำหนด API คุณสามารถทำสิ่ง ใดสิ่งหนึ่ง จากสามสิ่งต่อไปนี้:
    • อนุญาตให้ดำเนินการตรวจสอบต่อไป (อย่าทำอะไรเลย.)
    • ปิดการใช้งานการตรวจสอบโดยเพิ่มสิ่งต่อไปนี้ใน java_sdk_library :
      unsafe_ignore_missing_latest_api: true,
    • จัดเตรียม API ว่างสำหรับโมดูล java_sdk_library ใหม่โดยการสร้างไฟล์ข้อความเปล่าชื่อ module_name.txt ใน ไดเร็กทอรี version/scope/api
  • หากมีการติดตั้งไลบรารีการใช้งานสำหรับรันไทม์ ไฟล์ XML จะถูกสร้างขึ้นและติดตั้ง

java_sdk_library ทำงานอย่างไร

java_sdk_library ชื่อ X สร้างสิ่งต่อไปนี้:

  1. ไลบรารีการใช้งานสองสำเนา: ไลบรารีหนึ่งชื่อ X และอีกไลบรารีหนึ่งเรียกว่า X.impl ติดตั้ง Library X บนอุปกรณ์แล้ว ไลบรารี X.impl จะอยู่ที่นั่นก็ต่อเมื่อโมดูลอื่นจำเป็นต้องเข้าถึงไลบรารีการใช้งานอย่างชัดเจน เช่น เพื่อใช้ในการทดสอบ โปรดทราบว่าการเข้าถึงโดยชัดแจ้งนั้นแทบจะไม่จำเป็นเลย
  2. สามารถเปิดและปิดใช้งานขอบเขตเพื่อปรับแต่งการเข้าถึงได้ (คล้ายกับตัวแก้ไขการเข้าถึงคำหลัก Java ขอบเขตสาธารณะให้การเข้าถึงที่หลากหลาย ขอบเขตการทดสอบประกอบด้วย API ที่ใช้ในการทดสอบเท่านั้น) สำหรับแต่ละขอบเขตที่เปิดใช้งาน ไลบรารีจะสร้างสิ่งต่อไปนี้:
    • โมดูลแหล่งที่มาของ Stubs (ของประเภทโมดูล droidstubs ) - ใช้แหล่งที่มาของการนำไปใช้งานและส่งออกชุดของแหล่งที่มาของ Stub พร้อมกับไฟล์ข้อกำหนด API
    • ไลบรารี stubs (ของประเภทโมดูล java_library ) - เป็นเวอร์ชันที่คอมไพล์ของ stubs libs ที่ใช้ในการคอมไพล์สิ่งนี้ไม่เหมือนกับที่มอบให้กับ java_sdk_library ซึ่งช่วยให้มั่นใจว่ารายละเอียดการใช้งานจะไม่รั่วไหลไปยัง stubs API
    • หากคุณต้องการไลบรารีเพิ่มเติมเพื่อคอมไพล์ stubs ให้ใช้คุณสมบัติ stub_only_libs และ stub_only_static_libs เพื่อจัดหาไลบรารีเหล่านั้น

หาก java_sdk_library ถูกเรียกว่า “ X ” และถูกคอมไพล์โดยใช้ชื่อ “ X ” ให้อ้างอิงถึงมันด้วยวิธีนั้นเสมอและอย่าแก้ไขมัน โครงสร้างจะเลือกไลบรารีที่เหมาะสม เพื่อให้แน่ใจว่าคุณมีไลบรารีที่เหมาะสมที่สุด ให้ตรวจสอบ stub ของคุณเพื่อดูว่าบิลด์มีข้อผิดพลาดหรือไม่ ทำการแก้ไขที่จำเป็นโดยใช้คำแนะนำนี้:

  • ตรวจสอบว่าคุณมีไลบรารีที่เหมาะสมโดยดูที่บรรทัดคำสั่งและตรวจสอบว่ามีไลบรารีใดบ้างในรายการเพื่อกำหนดขอบเขตของคุณ:
    • ขอบเขตกว้างเกินไป: ไลบรารีที่ขึ้นต่อกันต้องมีขอบเขตของ API ที่แน่นอน แต่คุณเห็น API ที่รวมอยู่ในไลบรารีที่อยู่นอกขอบเขตนั้น เช่น API ของระบบที่รวมอยู่ใน API สาธารณะ
    • ขอบเขตแคบเกินไป: ไลบรารีที่ขึ้นต่อกันไม่สามารถเข้าถึงไลบรารีที่จำเป็นทั้งหมด ตัวอย่างเช่น ไลบรารีที่ขึ้นต่อกันจำเป็นต้องใช้ API ของระบบ แต่ได้รับ API สาธารณะแทน ซึ่งมักจะส่งผลให้เกิดข้อผิดพลาดในการคอมไพล์เนื่องจาก API ที่จำเป็นขาดหายไป
  • หากต้องการแก้ไขไลบรารี ให้ทำอย่างใด อย่างหนึ่ง ต่อไปนี้:
    • เปลี่ยน sdk_version เพื่อเลือกเวอร์ชันที่คุณต้องการ หรือ
    • ระบุไลบรารีที่เหมาะสมอย่างชัดเจน เช่น <X>.stubs หรือ <X>.stubs.system

การใช้งาน java_sdk_library X

ไลบรารีการใช้งาน X จะถูกใช้เมื่อมีการอ้างอิงจาก apex.java_libs อย่างไรก็ตาม เนื่องจากข้อจำกัดของ Soong เมื่อไลบรารี X ถูกอ้างอิงจากโมดูล java_sdk_library อื่น ภายในไลบรารี APEX เดียวกัน จึงต้องใช้ X.impl อย่างชัดเจน ไม่ใช่ไลบรารี X

เมื่อ java_sdk_library ถูกอ้างอิงจากที่อื่น ไลบรารี stubs จะถูกนำมาใช้ ไลบรารี stubs ถูกเลือกตามการตั้งค่าคุณสมบัติ sdk_version ของโมดูลที่ขึ้นต่อกัน ตัวอย่างเช่น โมดูลที่ระบุ sdk_version: "current" ใช้ stub สาธารณะ ในขณะที่โมดูลที่ระบุ sdk_version: "system_current" ใช้ stub ระบบ หากไม่พบรายการที่ตรงกันทั้งหมด ระบบจะใช้ไลบรารี Stub ที่ใกล้เคียงที่สุด java_sdk_library ที่ให้บริการเฉพาะ API สาธารณะจะจัดหา stub สาธารณะให้กับทุกคน

สร้างโฟลว์ด้วยไลบรารี Java SDK
รูปที่ 1 สร้างโฟลว์ด้วยไลบรารี Java SDK

ตัวอย่างและแหล่งที่มา

คุณสมบัติ srcs และ api_packages ต้อง มีอยู่ใน java_sdk_library

java_sdk_library {
        name: "com.android.future.usb.accessory",
        srcs: ["src/**/*.java"],
        api_packages: ["com.android.future.usb"],
    }

AOSP แนะนำ (แต่ไม่จำเป็น) ว่าอินสแตนซ์ java_sdk_library ใหม่เปิดใช้งานขอบเขต API ที่ต้องการใช้อย่างชัดเจน คุณยังสามารถ (เป็นทางเลือก) ย้ายอินสแตนซ์ java_sdk_library ที่มีอยู่เพื่อเปิดใช้งานขอบเขต API ที่จะใช้อย่างชัดเจน:

java_sdk_library {
         name: "lib",
         public: {
           enabled: true,
         },
         system: {
           enabled: true,
         },
         …
    }

หากต้องการกำหนดค่าไลบรารี impl ที่ใช้สำหรับรันไทม์ ให้ใช้คุณสมบัติ java_library ปกติทั้งหมด เช่น hostdex , compile_dex และ errorprone

java_sdk_library {
        name: "android.test.base",

        srcs: ["src/**/*.java"],

        errorprone: {
          javacflags: ["-Xep:DepAnn:ERROR"],
        },

        hostdex: true,

        api_packages: [
            "android.test",
            "android.test.suitebuilder.annotation",
            "com.android.internal.util",
            "junit.framework",
        ],

        compile_dex: true,
    }

หากต้องการกำหนดค่าไลบรารี stubs ให้ใช้คุณสมบัติต่อไปนี้:

  • merge_annotations_dirs และ merge_inclusion_annotations_dirs
  • api_srcs : รายการไฟล์ต้นฉบับเสริมที่เป็นส่วนหนึ่งของ API แต่ไม่ใช่ส่วนหนึ่งของไลบรารีรันไทม์
  • stubs_only_libs : รายการไลบรารี Java ที่อยู่ใน classpath เมื่อสร้าง stubs
  • hidden_api_packages : รายการชื่อแพ็คเกจที่ต้องซ่อนจาก API
  • droiddoc_options : อาร์กิวเมนต์เพิ่มเติมสำหรับ metalava
  • droiddoc_option_files : แสดงรายการไฟล์ที่สามารถอ้างอิงได้จากภายใน droiddoc_options โดยใช้ $(location <label>) โดยที่ <file> เป็นรายการในรายการ
  • annotations_enabled

java_sdk_library เป็น java_library แต่ไม่ใช่โมดูล droidstubs จึงไม่รองรับคุณสมบัติ droidstubs ทั้งหมด ตัวอย่างต่อไปนี้นำมาจากไฟล์ บิลด์ไลบรารี android.test.mock

java_sdk_library {
        name: "android.test.mock",

        srcs: [":android-test-mock-sources"],
        api_srcs: [
            // Note: The following aren’t APIs of this library. Only APIs under the
            // android.test.mock package are taken. These do provide private APIs
            // to which android.test.mock APIs reference. These classes are present
            // in source code form to access necessary comments that disappear when
            // the classes are compiled into a Jar library.
            ":framework-core-sources-for-test-mock",
            ":framework_native_aidl",
        ],

        libs: [
            "framework",
            "framework-annotations-lib",
            "app-compat-annotations",
            "Unsupportedappusage",
        ],

        api_packages: [
            "android.test.mock",
        ],
        permitted_packages: [
            "android.test.mock",
        ],
        compile_dex: true,
        default_to_stubs: true,
    }

การรักษาความเข้ากันได้แบบย้อนหลัง

ระบบบิลด์จะตรวจสอบว่า API รักษาความเข้ากันได้แบบย้อนหลังหรือไม่โดยการเปรียบเทียบไฟล์ API ล่าสุดกับไฟล์ API ที่สร้างขึ้นในขณะสร้าง java_sdk_library ดำเนินการตรวจสอบความเข้ากันได้โดยใช้ข้อมูลที่จัดทำโดย prebuilt_apis ไลบรารีทั้งหมดที่สร้างด้วย java_sdk_library ต้องมีไฟล์ API ใน api_dirs เวอร์ชันล่าสุดใน prebuilt_apis เมื่อคุณเผยแพร่เวอร์ชัน API จะแสดงรายการไฟล์และไลบรารี stubs ด้วย dist build ด้วย PRODUCT=sdk_phone_armv7-sdk

คุณสมบัติ api_dirs คือรายการไดเรกทอรีเวอร์ชัน API ใน prebuilt_apis ไดเร็กทอรีเวอร์ชัน API ต้องอยู่ที่ระดับไดเร็กทอรี Android.bp

prebuilt_apis {
       name: "foo",
       api_dirs: [
           "1",
           "2",
             ....
           "30",
           "current",
       ],
    }

กำหนดค่าไดเร็กทอรีด้วย version / scope /api/ โครงสร้างภายใต้ไดเร็กทอรีที่สร้างไว้ล่วงหน้า version สอดคล้องกับระดับ API และ scope กำหนดว่าไดเร็กทอรีเป็นแบบสาธารณะ ระบบ หรือแบบทดสอบ

  • version / scope มีไลบรารี Java
  • version / scope /api มีไฟล์ API .txt สร้างไฟล์ข้อความเปล่าชื่อ module_name .txt และ module_name -removed.txt ที่นี่
     ├── 30
          │   ├── public
          │   │   ├── api
          │   │   │   ├── android.test.mock-removed.txt
          │   │   │   └── android.test.mock.txt
          │   │   └── android.test.mock.jar
          │   ├── system
          │   │   ├── api
          │   │   │   ├── android.test.mock-removed.txt
          │   │   │   └── android.test.mock.txt
          │   │   └── android.test.mock.jar
          │   └── test
          │       ├── api
          │       │   ├── android.test.mock-removed.txt
          │       │   └── android.test.mock.txt
          │       └── android.test.mock.jar
          └── Android.bp