تنفيذ مكتبة Java SDK

يحتوي نظام Android الأساسي على عدد كبير من مكتبات Java المشتركة التي يمكن تضمينها اختياريًا في مسار فئة التطبيقات مع علامة <uses-library> في بيان التطبيق. ترتبط التطبيقات بهذه المكتبات ، لذا تعامل معها مثل بقية Android API من حيث التوافق ومراجعة واجهة برمجة التطبيقات ودعم الأدوات. لاحظ ، مع ذلك ، أن معظم المكتبات لا تحتوي على هذه الميزات.

يساعد نوع الوحدة النمطية java_sdk_library في إدارة المكتبات من هذا النوع. يمكن لمصنعي الأجهزة استخدام هذه الآلية لمكتبات Java المشتركة الخاصة بهم ، للحفاظ على التوافق مع الإصدارات السابقة لواجهات برمجة التطبيقات الخاصة بهم. إذا كان مصنعو الأجهزة يستخدمون مكتبات Java المشتركة الخاصة بهم من خلال علامة <uses-library> بدلاً من مسار java_sdk_library ، يمكن لـ java_sdk_library التحقق من أن مكتبات Java هذه مستقرة API.

تقوم java_sdk_library بتنفيذ واجهات برمجة تطبيقات SDK اختيارية لتستخدمها التطبيقات. تقوم المكتبات المنفذة من خلال java_sdk_library في ملف الإنشاء ( Android.bp ) بتنفيذ العمليات التالية:

  • يتم إنشاء مكتبات stubs.system لتشمل stub و stubs و stubs.test . يتم إنشاء مكتبات الرتب @SystemApi هذه عن طريق التعرف على التعليقات التوضيحيةhide و @hide و @TestApi .
  • تدير java_sdk_library ملفات مواصفات API (مثل current.txt ) في دليل فرعي لواجهة برمجة التطبيقات. يتم فحص هذه الملفات مقابل أحدث رمز للتأكد من أنها أحدث الإصدارات. إذا لم تكن كذلك ، فستتلقى رسالة خطأ تشرح كيفية تحديثها. راجع يدويًا جميع تغييرات التحديث للتأكد من أنها تتطابق مع توقعاتك.

    لتحديث جميع واجهات برمجة التطبيقات ، استخدم m update-api . للتحقق من تحديث API ، استخدم m checkapi .
  • يتم فحص ملفات مواصفات واجهة برمجة التطبيقات مقابل أحدث إصدارات Android المنشورة للتأكد من أن واجهة برمجة التطبيقات متوافقة مع الإصدارات السابقة. تضع الوحدات النمطية java_sdk_library المتوفرة كجزء من AOSP إصداراتها التي تم إصدارها مسبقًا في prebuilts/sdk/<latest number> .
  • فيما يتعلق بفحوصات ملفات مواصفات API ، يمكنك القيام بأحد الأشياء الثلاثة التالية:
    • السماح للشيكات المضي قدما. (لا تفعل أي شيء.)
    • تعطيل الشيكات عن طريق إضافة ما يلي إلى java_sdk_library :
      unsafe_ignore_missing_latest_api: true,
    • قم بتوفير واجهات برمجة تطبيقات فارغة لوحدات 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 ، يوفر النطاق العام نطاقًا واسعًا من الوصول ؛ يحتوي نطاق الاختبار على واجهات برمجة التطبيقات المستخدمة فقط في الاختبار.) لكل نطاق ممكّن ، تنشئ المكتبة ما يلي:
    • وحدة مصدر stubs (من نوع وحدة droidstubs ) - تستهلك مصدر التنفيذ وتخرج مجموعة من مصادر كعب الروتين مع ملف مواصفات API.
    • مكتبة جذرية (من نوع الوحدة النمطية java_library ) - هي النسخة المجمعة من الأجزاء الجذرية. libs المستخدمة لتجميع هذا ليست هي نفسها التي تم توفيرها java_sdk_library ، مما يضمن عدم تسرب تفاصيل التنفيذ إلى أجزاء API.
    • إذا كنت بحاجة إلى مكتبات إضافية لتجميع التنسيقات ، فاستخدم stub_only_libs و stub_only_static_libs لتزويدها.

إذا كانت java_sdk_library تسمى " X " ، ويتم تجميعها مقابل " X " ، فارجع إليها دائمًا بهذه الطريقة ولا تقم بتعديلها. سيختار البناء مكتبة مناسبة. للتأكد من أن لديك المكتبة الأكثر ملاءمة ، افحص بذراتك لمعرفة ما إذا كان الإصدار قد تسبب في حدوث أخطاء. قم بإجراء أي تصحيحات ضرورية باستخدام هذا التوجيه:

  • تحقق من أن لديك مكتبة مناسبة من خلال النظر في سطر الأوامر وفحص العناصر الأساسية المدرجة هناك لتحديد نطاقك:
    • النطاق واسع جدًا: تحتاج المكتبة المعتمدة إلى نطاق معين من واجهات برمجة التطبيقات. لكنك ترى واجهات برمجة التطبيقات المضمنة في المكتبة والتي تقع خارج هذا النطاق ، مثل واجهات برمجة التطبيقات للنظام المضمنة في واجهات برمجة التطبيقات العامة.
    • النطاق ضيق للغاية: لا تمتلك المكتبة المعتمدة حق الوصول إلى جميع المكتبات المطلوبة. على سبيل المثال ، تحتاج المكتبة المعتمدة إلى استخدام واجهة برمجة تطبيقات النظام ولكنها تحصل على واجهة برمجة التطبيقات العامة بدلاً من ذلك. ينتج عن هذا عادةً خطأ في الترجمة لأن واجهات برمجة التطبيقات المطلوبة مفقودة.
  • لإصلاح المكتبة ، قم بتنفيذ أحد الإجراءات التالية فقط:
    • قم بتغيير 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 وفقًا لإعداد خاصية sdk_version للوحدة النمطية. على سبيل المثال ، الوحدة النمطية التي تحدد sdk_version: "current" تستخدم "Current" وحدات التشغيل الجذرية العامة ، بينما تستخدم الوحدة النمطية التي تحدد sdk_version: "system_current" النظام الأساسي. إذا تعذر العثور على تطابق تام ، فسيتم استخدام أقرب مكتبة كعب. java_sdk_library التي توفر واجهة برمجة تطبيقات عامة فقط بتزويد وحدات التشغيل الجذرية العامة للجميع.

بناء التدفق باستخدام مكتبة 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 الموجودة لتمكين نطاقات واجهة برمجة التطبيقات التي سيستخدمونها بشكل صريح:

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 and merge_inclusion_annotations_dirs .
  • api_srcs : قائمة ملفات المصدر الاختيارية التي تعد جزءًا من API ولكنها ليست جزءًا من مكتبة وقت التشغيل.
  • stubs_only_libs : قائمة مكتبات Java الموجودة في مسار الفصل عند إنشاء الوحدات الجذعية.
  • hidden_api_packages : قائمة بأسماء الحزم التي يجب إخفاؤها من واجهة برمجة التطبيقات.
  • droiddoc_options : وسيطة إضافية للميتالافا .
  • 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 build with 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/ الهيكل ضمن دليل prebuilts. 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