پیاده سازی Java SDK Library

پلتفرم Android حاوی تعداد زیادی کتابخانه مشترک جاوا است که می‌توانند به صورت اختیاری با تگ <uses-library> در مانیفست برنامه در مسیر کلاس برنامه‌ها قرار گیرند. برنامه‌ها با این کتابخانه‌ها پیوند دارند، بنابراین از نظر سازگاری، بررسی API و پشتیبانی ابزار، مانند بقیه API Android با آن‌ها رفتار کنید. البته توجه داشته باشید که اکثر کتابخانه ها این ویژگی ها را ندارند.

نوع ماژول java_sdk_library به مدیریت کتابخانه هایی از این نوع کمک می کند. سازندگان دستگاه می‌توانند از این مکانیسم برای کتابخانه‌های جاوای مشترک خود استفاده کنند تا سازگاری با APIهای خود را حفظ کنند. اگر سازندگان دستگاه‌ها از کتابخانه‌های جاوای مشترک خود از طریق تگ <uses-library> به جای مسیر bootclass استفاده کنند، java_sdk_library می‌تواند تأیید کند که آن کتابخانه‌های جاوا دارای API پایدار هستند.

java_sdk_library API های اختیاری SDK را برای استفاده توسط برنامه ها پیاده سازی می کند. کتابخانه های پیاده سازی شده از طریق java_sdk_library در فایل ساخت شما ( Android.bp ) عملیات زیر را انجام می دهند:

  • کتابخانه های خرد برای شامل stubs ، stubs.system و stubs.test تولید می شوند. این کتابخانه‌های خرد با تشخیص @hide ، @SystemApi و @TestApi حاشیه‌نویسی ایجاد می‌شوند.
  • java_sdk_library فایل های مشخصات API (مانند current.txt ) را در یک زیر شاخه API مدیریت می کند. این فایل‌ها با آخرین کد بررسی می‌شوند تا اطمینان حاصل شود که جدیدترین نسخه‌ها هستند. اگر اینطور نیست، پیام خطایی دریافت می کنید که نحوه به روز رسانی آنها را توضیح می دهد. همه تغییرات به‌روزرسانی را به‌صورت دستی مرور کنید تا مطمئن شوید که با انتظارات شما مطابقت دارند.

    برای به‌روزرسانی همه APIها، از m update-api استفاده کنید. برای تأیید اینکه یک API به روز است، از m checkapi استفاده کنید.
  • فایل‌های مشخصات API با جدیدترین نسخه‌های اندروید منتشر شده بررسی می‌شوند تا اطمینان حاصل شود که 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 . کتابخانه X روی دستگاه نصب شده است. Library X.impl تنها در صورتی وجود دارد که دسترسی صریح به کتابخانه پیاده‌سازی توسط ماژول‌های دیگر مورد نیاز باشد، مانند استفاده در آزمایش. توجه داشته باشید که دسترسی صریح به ندرت مورد نیاز است.
  2. برای سفارشی کردن دسترسی می توان Scope ها را فعال و غیرفعال کرد. (مشابه اصلاح‌کننده‌های دسترسی به کلیدواژه جاوا، یک محدوده عمومی طیف وسیعی از دسترسی را فراهم می‌کند؛ یک محدوده آزمایشی حاوی APIهایی است که فقط در آزمایش استفاده می‌شوند.) برای هر محدوده فعال، کتابخانه موارد زیر را ایجاد می‌کند:
    • یک ماژول منبع خرد (از نوع ماژول droidstubs ) - منبع پیاده سازی را مصرف می کند و مجموعه ای از منابع خرد را به همراه فایل مشخصات API خروجی می دهد.
    • یک کتابخانه خرد (از نوع ماژول java_library ) - نسخه کامپایل شده خرده ها است. لبه‌هایی که برای کامپایل این مورد استفاده می‌شوند با مواردی که برای java_sdk_library ارائه شده است، نیستند، که تضمین می‌کند جزئیات پیاده‌سازی به قسمت‌های خرد API درز نمی‌کنند.
    • اگر برای کامپایل کردن به کتابخانه‌های اضافی نیاز دارید، از ویژگی‌های stub_only_libs و stub_only_static_libs برای تهیه آنها استفاده کنید.

اگر یک java_sdk_library " X " نامیده می شود و در برابر " X " کامپایل می شود، همیشه به آن مراجعه کنید و آن را تغییر ندهید. بیلد یک کتابخانه مناسب را انتخاب می کند. برای اطمینان از اینکه مناسب‌ترین کتابخانه را دارید، موارد خرد خود را بررسی کنید تا ببینید آیا ساخت خطاهایی ایجاد کرده است. هر گونه اصلاحات لازم را با استفاده از این راهنما انجام دهید:

  • با نگاه کردن به خط فرمان و بررسی اینکه کدام موارد خرد در آنجا فهرست شده‌اند تا محدوده شما را مشخص کنید، تأیید کنید که کتابخانه مناسبی دارید:
    • دامنه بسیار گسترده است: کتابخانه وابسته به محدوده خاصی از 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" را مشخص می کند، از خرده های عمومی استفاده می کند، در حالی که ماژولی که sdk_version: "system_current" از خرده های سیستم استفاده می کند. اگر منطبق دقیقی پیدا نشد، از نزدیکترین کتابخانه خرد استفاده می شود. یک java_sdk_library که فقط یک API عمومی ارائه می‌کند، خرد عمومی را برای همه فراهم می‌کند.

ساخت جریان با کتابخانه جاوا SDK
شکل 1. ساخت جریان با کتابخانه جاوا 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,
    }

برای پیکربندی کتابخانه های خرد، از ویژگی های زیر استفاده کنید:

  • merge_annotations_dirs و merge_inclusion_annotations_dirs .
  • api_srcs : لیستی از فایل های منبع اختیاری که بخشی از API هستند اما بخشی از کتابخانه زمان اجرا نیستند.
  • stubs_only_libs : لیستی از کتابخانه های جاوا که در مسیر کلاس در هنگام ساختن خرد قرار دارند.
  • 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 فایل‌ها و کتابخانه‌های خرد را می‌توان با ساخت dist با 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 شامل کتابخانه های جاوا است.
  • 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