Triển khai Thư viện SDK Java

Nền tảng Android chứa một số lượng lớn các thư viện Java dùng chung có thể được đưa vào đường dẫn lớp của ứng dụng một cách tùy ý bằng thẻ <uses-library> trong bảng kê khai ứng dụng. Các ứng dụng liên kết với các thư viện này, vì vậy hãy coi chúng giống như phần còn lại của API Android về khả năng tương thích, đánh giá API và hỗ trợ công cụ. Tuy nhiên, hãy lưu ý rằng hầu hết các thư viện không có những tính năng này.

Loại mô-đun java_sdk_library giúp quản lý các thư viện thuộc loại này. Các nhà sản xuất thiết bị có thể sử dụng cơ chế này cho các thư viện Java dùng chung của riêng họ để duy trì khả năng tương thích ngược cho các API của họ. Nếu nhà sản xuất thiết bị sử dụng thư viện Java được chia sẻ của riêng họ thông qua thẻ <uses-library> thay vì đường dẫn lớp khởi động, java_sdk_library có thể xác minh rằng các thư viện Java đó có API ổn định.

java_sdk_library triển khai các API SDK tùy chọn để ứng dụng sử dụng. Các thư viện được triển khai thông qua java_sdk_library trong tệp xây dựng của bạn ( Android.bp ) thực hiện các thao tác sau:

  • Các thư viện sơ khai được tạo để bao gồm stubs , stubs.systemstubs.test . Các thư viện sơ khai này được tạo bằng cách nhận dạng các chú thích @hide , @SystemApi@TestApi .
  • java_sdk_library quản lý các tệp đặc tả API (chẳng hạn như current.txt ) trong thư mục con API. Các tệp này được kiểm tra dựa trên mã mới nhất để đảm bảo rằng chúng là phiên bản mới nhất. Nếu không, bạn sẽ nhận được thông báo lỗi giải thích cách cập nhật chúng. Xem xét thủ công tất cả các thay đổi cập nhật để đảm bảo rằng chúng phù hợp với mong đợi của bạn.

    Để cập nhật tất cả các API, hãy sử dụng m update-api . Để xác minh rằng API đã được cập nhật, hãy sử dụng m checkapi .
  • Các tệp đặc tả API được kiểm tra dựa trên các phiên bản Android được xuất bản gần đây nhất để đảm bảo rằng API tương thích ngược với các bản phát hành trước đó. Các mô-đun java_sdk_library được cung cấp như một phần của AOSP đặt các phiên bản đã phát hành trước đó của chúng vào prebuilts/sdk/<latest number> .
  • Đối với việc kiểm tra tệp đặc tả API, bạn có thể thực hiện một trong ba điều sau:
    • Cho phép tiến hành kiểm tra. (Đừng làm gì cả.)
    • Vô hiệu hóa kiểm tra bằng cách thêm phần sau vào java_sdk_library :
      unsafe_ignore_missing_latest_api: true,
    • Cung cấp các API trống cho các mô-đun java_sdk_library mới bằng cách tạo các tệp văn bản trống có tên module_name.txt trong thư mục version/scope/api .
  • Nếu thư viện triển khai cho thời gian chạy được cài đặt thì tệp XML sẽ được tạo và cài đặt.

Cách hoạt động của java_sdk_library

Một java_sdk_library có tên X tạo ra như sau:

  1. Hai bản sao của thư viện triển khai: một thư viện có tên X và một thư viện khác có tên X.impl . Thư viện X được cài đặt trên thiết bị. Thư viện X.impl chỉ có nếu các mô-đun khác cần quyền truy cập rõ ràng vào thư viện triển khai, chẳng hạn như để sử dụng trong thử nghiệm. Lưu ý rằng hiếm khi cần truy cập rõ ràng.
  2. Phạm vi có thể được kích hoạt và vô hiệu hóa để tùy chỉnh quyền truy cập. (Tương tự như công cụ sửa đổi truy cập từ khóa Java, phạm vi công khai cung cấp phạm vi truy cập rộng; phạm vi thử nghiệm chứa các API chỉ được sử dụng trong thử nghiệm.) Đối với mỗi phạm vi được bật, thư viện sẽ tạo như sau:
    • Mô-đun nguồn sơ khai (thuộc loại mô droidstubs ) - sử dụng nguồn triển khai và xuất ra một tập hợp các nguồn sơ khai cùng với tệp đặc tả API.
    • Thư viện sơ khai (thuộc loại mô-đun java_library ) - là phiên bản được biên dịch của sơ khai. Các lib được sử dụng để biên dịch phần này không giống với các lib được cung cấp cho java_sdk_library , nhằm đảm bảo các chi tiết triển khai không bị rò rỉ vào các nhánh API.
    • Nếu bạn cần các thư viện bổ sung để biên dịch các sơ khai, hãy sử dụng các thuộc tính stub_only_libsstub_only_static_libs để cung cấp chúng.

Nếu một java_sdk_library có tên là “ X ”, và đang được biên dịch thành “ X ”, hãy luôn tham chiếu đến nó theo cách đó và không sửa đổi nó. Bản dựng sẽ chọn một thư viện thích hợp. Để đảm bảo rằng bạn có thư viện thích hợp nhất, hãy kiểm tra sơ khai của bạn để xem liệu bản dựng có gây ra lỗi hay không. Thực hiện mọi chỉnh sửa cần thiết bằng cách sử dụng hướng dẫn này:

  • Xác minh rằng bạn có thư viện thích hợp bằng cách xem dòng lệnh và kiểm tra xem các sơ khai nào được liệt kê ở đó để xác định phạm vi của bạn:
    • Phạm vi quá rộng: Thư viện tùy thuộc cần có phạm vi API nhất định. Tuy nhiên, bạn thấy các API có trong thư viện nằm ngoài phạm vi đó, chẳng hạn như các API hệ thống được bao gồm trong các API công khai.
    • Phạm vi quá hẹp: Thư viện tùy thuộc không có quyền truy cập vào tất cả các thư viện cần thiết. Ví dụ: thư viện tùy thuộc cần sử dụng API hệ thống nhưng thay vào đó lại lấy API công khai. Điều này thường dẫn đến lỗi biên dịch vì thiếu các API cần thiết.
  • Để sửa thư viện, chỉ thực hiện một trong các thao tác sau:
    • Thay đổi sdk_version để chọn phiên bản bạn cần. HOẶC
    • Chỉ định rõ ràng thư viện thích hợp, chẳng hạn như <X>.stubs hoặc <X>.stubs.system .

Cách sử dụng java_sdk_library X

Thư viện triển khai X được sử dụng khi nó được tham chiếu từ apex.java_libs . Tuy nhiên, do hạn chế của Soong, khi thư viện X được tham chiếu từ một mô-đun java_sdk_library khác trong cùng thư viện APEX, X.impl phải được sử dụng rõ ràng chứ không phải thư viện X .

Khi java_sdk_library được tham chiếu từ nơi khác, thư viện sơ khai sẽ được sử dụng. Thư viện sơ khai được chọn theo cài đặt thuộc tính sdk_version của mô-đun tùy thuộc. Ví dụ: một mô-đun chỉ định sdk_version: "current" sử dụng các sơ khai công khai, trong khi một mô-đun chỉ định sdk_version: "system_current" sử dụng các sơ khai hệ thống. Nếu không thể tìm thấy kết quả khớp chính xác, thư viện sơ khai gần nhất sẽ được sử dụng. Một java_sdk_library chỉ cung cấp API công khai sẽ cung cấp các sơ khai công khai cho mọi người.

Xây dựng quy trình với thư viện Java SDK
Hình 1. Luồng xây dựng với thư viện Java SDK

Ví dụ và nguồn

Các thuộc tính srcsapi_packages phải có trong java_sdk_library .

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

AOSP khuyến nghị (nhưng không yêu cầu) rằng các phiên bản java_sdk_library mới sẽ kích hoạt rõ ràng phạm vi API mà chúng muốn sử dụng. Bạn cũng có thể (tùy chọn) di chuyển các phiên bản java_sdk_library hiện có để kích hoạt rõ ràng phạm vi API mà chúng sẽ sử dụng:

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

Để định cấu hình thư viện impl được sử dụng cho thời gian chạy, hãy sử dụng tất cả các thuộc tính java_library thông thường, chẳng hạn như hostdex , compile_dexerrorprone .

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,
    }

Để định cấu hình thư viện sơ khai, hãy sử dụng các thuộc tính sau:

  • merge_annotations_dirsmerge_inclusion_annotations_dirs .
  • api_srcs : Danh sách các tệp nguồn tùy chọn là một phần của API nhưng không phải là một phần của thư viện thời gian chạy.
  • stubs_only_libs : Danh sách các thư viện Java có trong đường dẫn lớp khi xây dựng sơ khai.
  • hidden_api_packages : Danh sách tên gói phải ẩn khỏi API.
  • droiddoc_options : Đối số bổ sung cho metalava .
  • droiddoc_option_files : Liệt kê các tệp có thể được tham chiếu từ bên trong droiddoc_options bằng cách sử dụng $(location <label>) , trong đó <file> là một mục trong danh sách.
  • annotations_enabled .

java_sdk_library là một java_library , nhưng nó không phải là mô-đun droidstubs và do đó không hỗ trợ tất cả các thuộc tính droidstubs . Ví dụ sau được lấy từ tệp xây dựng thư viện 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,
    }

Duy trì khả năng tương thích ngược

Hệ thống xây dựng kiểm tra xem các API có duy trì khả năng tương thích ngược hay không bằng cách so sánh các tệp API mới nhất với các tệp API được tạo tại thời điểm xây dựng. java_sdk_library thực hiện kiểm tra tính tương thích bằng cách sử dụng thông tin được cung cấp bởi prebuilt_apis . Tất cả các thư viện được xây dựng bằng java_sdk_library phải có tệp API trong phiên bản mới nhất của api_dirs trong prebuilt_apis . Khi bạn phát hành phiên bản, bạn có thể lấy danh sách API và thư viện sơ khai bằng cách xây dựng dist với PRODUCT=sdk_phone_armv7-sdk .

Thuộc tính api_dirs là danh sách các thư mục phiên bản API trong prebuilt_apis . Các thư mục phiên bản API phải được đặt ở cấp thư mục Android.bp .

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

Định cấu hình các thư mục với cấu trúc version / scope /api/ trong thư mục dựng sẵn. version tương ứng với cấp độ và scope API xác định xem thư mục đó là công khai, hệ thống hay thử nghiệm.

  • version / scope chứa các thư viện Java.
  • version / scope /api chứa các tệp .txt API. Tạo các tệp văn bản trống có tên module_name .txtmodule_name -removed.txt tại đây.
     ├── 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